Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: QT опять сигналы-слоты  (Прочитано 29181 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« : 29-10-2015 10:26 » 

Здравствуйте, помогите, пожалуйста.

Есть некоторое количество CheckBox, которые создаются в программе.
Один из них   управляет все остальными:
 1 если он выбран, то у всех появляется "галочка";
 2 если он сброшен, то и другие сбрасываются.

Типа "ВСЕ" выбираем или снимаем.

Это в программе я реализовала с помощью  своего слота на сигнал stateChanged для всех CheckBox:

if(sender() == &chb1[0])
       for(int i=1;i<nn1;i++)
           chb1.setChecked(chb1[0].isChecked());

А вот, что не получается:
если у любого другого CheckBox снять признак выбора, то он должен сняться у главного, чтобы все остальные не изменились.

Получается, что как только в слоте я снимаю признак выбора появляется сигнал stateChanged ,  в результате - все сбрасываются.
 
Что-то понятно из моих объяснений ?

Мб вопрос в том, как определить изменение состояние произошло от нажатия на этот CheckBox или изменение состояния вторично,
те это результат нажатия на другой CheckBox.

Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 29-10-2015 12:05 » 

На самом деле это ТРИ состояния: 1. ВСЕ ДА 2. ВСЕ НЕТ 3. ЧАСТИЧНО

Как быть с этим?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #2 : 29-10-2015 12:19 » 

И?
Частично и не получается.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #3 : 29-10-2015 13:09 » 

Я с QT не играюсь, в VS есть такой стиль у чекбокса Tri-state = true  (в ресурсах BS_AUTO3STATE). Он позволяет отображать три состояния чекбокса

Если же у тебя проблемы с "обратной связью", то лучше всего разделить UI от данных. Те каждый чекбокс изменяет состояние в некой структуре данных, в данном случае я бы использовал для подчинённых чекбоксов bitset, для главного - три состояния. А чекбоксы служат для отображения этой структуры и изменения единичных состояний.

К примеру:
0  (0-off,  1-on, 2-mixed)
00000 (0-off,  1-on)

    Master OFF
        Slave 1  OFF
        Slave 2  OFF
        Slave 3  OFF
        Slave 4  OFF
        Slave 5  OFF
 
Пользователь кликает на Slave 3 т.е. переводит его в ON, это состояние заносится в структуру данных и изменяется состояние поля данных мастера
2
00100

после этого актуализируется состояние всех чекбоксов в UI

    Master MIX
        Slave 1  OFF
        Slave 2  OFF
        Slave 3  ON
        Slave 4  OFF
        Slave 5  OFF

И тд.

Ну вот типа иллюстрации

* ss1.jpg (8.4 Кб - загружено 2059 раз.)
* TestChkBox.zip (185.89 Кб - загружено 895 раз.)
« Последнее редактирование: 29-10-2015 15:23 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 29-10-2015 16:44 » 

ann_nef, с сигналами таким образом только запутаешь логику

тебе нужно:

галка all

галка ch1
галка ch2
галка ch3

сигнал "все" заводишь в слот slot_all
сигналы от остальных - в слот slot_check


Код:
void slot_all(bool)
{
  bool b=ui->all->isChecked();
      //тут можно цикл сделать, но когда мало - то лень лишние движения )
  {
      ui->ch1->setChecked(b);
      ui->ch2->setChecked(b);
      ui->ch3->setChecked(b);
  }
}

void slot_check(bool)
{
    if(QCheckBox* p=dynamic_cast<QCheckBox*>(sender()))
    {
         if(!p->isChecked())
         {
              ui->all->setChecked(0);
         }

//а тут в цикле проверить - если все поставлены, выставить all тоже в 1
     }
}

для проверок в цикле контролы можно в вектор засунуть в конструкторе диалога

не компилировал, не проверял )
Записан

Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 30-10-2015 00:14 » 

Я бы вместо чекбокса-"начальника" над остальными сделал пару кнопок "установить все" и "сбросить все". И понятнее интуитивно, и замкнутого круга не будет, когда чекбоксы друг друга по цепочке переключают. С "начальником" слишком много лишней возни, и в использовании не очень удобен.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 30-10-2015 05:06 » 

Dale, ага, я бы тоже так сделал. А то и вообще голые галки, пусть сами ставят ) Всё физкультура Отлично
Записан

Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 30-10-2015 07:37 » 

Ну если галок реально много, пара лишних кнопок не повредят. А вот с "серой" галкой как-то невразумительно получается. Если в данный момент половина галок включена, что делать по клику на "серой"? Включить все? Выключить? Инвертировать? Реализовать любой из этих вариантов несложно, но вот юзабилити хромает на обе ноги...

Вообще в моем представлении хороший графический интерфейс - это когда панель управления выглядит как настоящая приборная, реализованная в железе. Представим чекбоксы как кнопки с подсветкой: раз нажал - включилась лампочка, второй раз нажал - выключилась. Над/под ними пара кнопок: "включить все" и "выключить все". А как выглядел бы на аппаратной панели "серый" чекбокс? Светится, но тускло? Я уже не говорю про головоломную логику его реализации и использования.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 30-10-2015 08:25 » 

так я не предлагал 3-позиционный, у меня в примере - либо поставлен, либо нет  . Тоже не понимаю серое состояние чекбокса и никогда не использую
Записан

ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #9 : 30-10-2015 10:48 » 

Алексей, вопрос у меня такой:
как только в slot_check  будет выполнена ui->all->setChecked(0);
1 будет подан сигнал об изменении all ТАК?
2 будет отработан slot_all ТАК?
3 следовательно все чекбоксы сбросятся. ТАК?

Или я не права? У меня так получилось

Похоже, что надо два доп.чекбокса "все" и "сброс".
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 30-10-2015 10:57 » 

ann_nef, я не проверял ) Но если срабатывает сигнал, и всё зацикливается, то сами разработчики Qt рекомендуют выставлять собственные флаги пребывания в слоте, вида

Код:
bool m_DoNotNow;//мембер класса, инициализация 0

void ...::slot_s1()
{
    if(m_DoNotNow)return;
    m_DoNotNow=1;

    ...
    ...

    m_DoNotNow=0;
}

void ...::slot_s2()
{
    if(m_DoNotNow)return;
    m_DoNotNow=1;

    ...
    ...

    m_DoNotNow=0;
}

понятно, что это дополнительные костыли, но тут всё зависит от того дизайна, который ты сооружаешь. Правильно же сказал Dale - просто сделай две кнопки, одна "Выставить всё", вторая "Сбросить всё". Дёшево и сердито
« Последнее редактирование: 30-10-2015 11:01 от Алексей++ » Записан

Sla
Модератор

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 30-10-2015 11:07 » 

Серый чекбокс - это неопределенное состояние


Например, при данном наборе этот чекбокс не действует

Если касательно приборной панели  или лампочки - не горят

на приборной панели
активная - зеленая
неактивная - красная

Недоступная  - не горит ничего

Можно было бы "прятать", но на панели не спрячешь

Т.е. серый чекбокс disabled
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 30-10-2015 11:13 » 

Нууу я и не говорю, что нужно обязательно и всенепременно использовать "серую" галку (кстати, спасибо за термин).
Я просто проиллюстрировал, что имел ввиду исходя из:  
Частично и не получается.

С другой стороны, непонимание ещё не показатель никчёмности. Ага

А вот с "серой" галкой как-то невразумительно получается. Если в данный момент половина галок включена, что делать по клику на "серой"? Включить все? Выключить? Инвертировать? Реализовать любой из этих вариантов несложно, но вот юзабилити хромает на обе ноги...

Во-первых. "Серую" галку придумал не я, и не я наделил её такими свойствами. А тот кто её придумал, тоже не сделал это просто так, от нечего делать. Во-вторых, причина непонимания заключается в том, что "серая" галка НЕ ПРЕДНАЗНАЧЕНА для управления, а исключительно для ОТОБРАЖЕНИЯ СОСТОЯНИЯ. Никто никогда не програмирует событие именно по "серой"  галке (я во всяком случае никогда с таким не встречался), причины уже озвучены - НИКТО не скажет однозначно, какие сателитные галки должны быть в этот момент включены, а какие нет.

Поэтому и с юзабильностью нет никаких проблем - ф-я остаётся прежней ВСЁ ВКЛ/ ВСЁ ВЫКЛ. Последовательность смены состояний, как представлено на картинке выше:

Первый клик - "чёрная" галка
Второй клик  - "серая" галка
Третий клик - нет галки ("белая" галка)

Таким образом, "серая" галка равнозначна по функциональности "чёрной", только с доп. информацией - хоть что-то, да осталось включённым (например, НЕ ВСЕ приборы включены, НО всё-таки какие-то включены), и клик по ней, как и в случае с "чёрной" галкой, означет "теперь! ВЫКЛЮЧИТЬ ВСЁ".

Вообще в моем представлении хороший графический интерфейс - это

Субъективно. А в общем случае это целиком и полностью решает заказачик. А он иногда ТАКОЕ нафантазирует, что хоть стой... Ага

Ну и теперь немножко субъективности от меня. Лёш, возьму твой "пример"
Тоже не понимаю серое состояние чекбокса и никогда не использую

Галок так много, что не помещаются на всё окно (по тем или иным, но объектвным причинам). Ты видишь только верхнюю часть, в которой видимые галки включены или выключены (выбирай на вкус). Как определить ВСЕ или НЕ ВСЕ? Ага
« Последнее редактирование: 30-10-2015 11:17 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 30-10-2015 11:19 » 

Джон, ну, я ж говорю - от дизайна и задумки зависит

В ТЗ указано : "Один из них   управляет все остальными:" Улыбаюсь  про индикацию частичной установленности нету в ТЗ, ничО не знаю  Ангел
« Последнее редактирование: 30-10-2015 11:21 от Алексей++ » Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #14 : 30-10-2015 11:21 » new

Dale, кстати, пример "серой" галки "на панели". Ага В данном случае на телевизионной (мониторной, и тп)

Синий - ВКЛ
Оранжевый - Standby (не знаю русского термина)
Не горит - Выкл

Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #15 : 30-10-2015 11:26 » 

В ТЗ указано : "Один из них   управляет все остальными:" Улыбаюсь

Правильно: ВСЕ включает или ВСЕ выключает, что я сделал не так? Моя галка работает как-то по-другому? Ага

Цитата
  про индикацию частичной установленности нету в ТЗ, ничО не знаю  angel:

А вот это уже вопрос "почему?". От неопытности, незнания? Поэтому я и "напомнил" о третьем состоянии. Которое, конечно же, и тут я полностью согласен с
Я уже не говорю про головоломную логику его реализации и использования.
требует, конечно не совсем головоломной логики, но определённые дополнительные телодвижения сделать надо. В сравнении с простой галкой.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Sla
Модератор

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 30-10-2015 11:26 » 

button type=(radio|checkbox)
Действительно много непониманий

кнопка может свойство ENABLED или DISABLED
и иметь значение.
свойства  ENABLED или DISABLED  доступны только в представлении и никак не влияют на работу контроллера
А значение  - непосредственно принимает участие в работе.
В случае disabled - может использоваться или дефолтное значение или игнорироваться ветка анализа



Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 30-10-2015 11:34 » 

Джон, какой был вопрос - такой и ответ, а ты зануда Отлично
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #18 : 30-10-2015 11:54 » 

а ты зануда Отлично

"Не то чтоб нуден, но до тошноты ворчлив." (с) Ага

Ладно, не хотите "серую", так даже ещё проще. В силу
если у любого другого CheckBox снять признак выбора, то он должен сняться у главного, чтобы все остальные не изменились.

Теперь "как доктор прописал"

* TestChkBox.zip (185.98 Кб - загружено 888 раз.)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 30-10-2015 12:11 » 

Джон, да да, вот это я и привёл в примере Ответ #4
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #20 : 30-10-2015 12:29 » 

Джон, да да, вот это я и привёл в примере Ответ #4

не компилировал, не проверял )

Я с QT не играюсь, посему вопрос, а вот тут

>>> ui->all->setChecked(0);

у тебя не получится, что ВСЕ выключатся? Ведь насколько я понял результатом будет вызов void slot_all(bool)?

зы По-прежнему я за разделение UI и данных. А всякие флажки и тп это детский сад на демонстрации.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 30-10-2015 13:09 » 

Джон, там предохранитель на такой случай - Ответ#10


Ещё есть методы - не сигналы или сигнал toggle - они могут не зайти в слот. Эксперимент надо )

Я тоже  за разделение. Но для сложных случаев. В Qt  (точнее - в редакторе QtCreator) морда накидывается очень быстро - когда случай простой, можно сделать и забыть
« Последнее редактирование: 30-10-2015 13:13 от Алексей++ » Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #22 : 30-10-2015 13:20 » 

Нууу... забыть, так забить.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 30-10-2015 16:25 » 

Можно по подробнее про #10:
во время выполнения функции "слота" может произойти событие и его обработка будет происходить параллельно? Или есть, какая-то повторная входимость? Или в результате изменения состояния checkbox программным методом, система также воспримет это, как событие изменения состояния, поместит его в некий стек и вызовет его обработчик. Не понятно, со стороны, как-то не стабильно выглядит.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #24 : 30-10-2015 17:57 » 

Aether, на память не смогу сказать, можно эксперименты нужные поставить и выяснить. Сигнально-слотовая рекурсия возможна.  Параллельного выполнения в примере нет - тут один поток (thread) используется - основной



Не поленился, проверил - никакой рекурсии не возникает при вызове слота setChecked()

Вот это прекрасно работает )

Код:
CSettingsDialog::CSettingsDialog
(
...
...
connect(ui->all,SIGNAL(clicked()),this,SLOT(slot_all()));
connect(ui->ch1,SIGNAL(clicked()),this,SLOT(slot_check()));
connect(ui->ch2,SIGNAL(clicked()),this,SLOT(slot_check()));
connect(ui->ch3,SIGNAL(clicked()),this,SLOT(slot_check()));

}

void CSettingsDialog::slot_all()
{
qDebug()<<"slot_all()";
bool b=ui->all->isChecked();

ui->ch1->setChecked(b);
ui->ch2->setChecked(b);
ui->ch3->setChecked(b);
}

void CSettingsDialog::slot_check()
{
qDebug()<<"slot_check()";
if(QCheckBox* p=dynamic_cast<QCheckBox*>(sender()))
{
if(1
  &&ui->ch1->isChecked()
  &&ui->ch2->isChecked()
  &&ui->ch3->isChecked()
  )
{
ui->all->setChecked(1);
}
else
{
if(!p->isChecked())
{
ui->all->setChecked(0);
}
}
}
}
Записан

Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 31-10-2015 07:31 » 

Спасибо.
Записан
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #26 : 02-11-2015 07:41 » 

Спасибо всем!
Сделала вариант с кнопками "ВСЕ" и "СБРОС", а также вариант с одной кнопкой "ВСЕ".
Отдельное спасибо Алексею++ за то, что не поленился поэкспериментировать.

Изначально ошиблась похоже в сигнале - использовала stateChanged или toggled. С clicked() всё получилось (этот сигнал Алексей и использовал).
Спасибо ещё раз. Теперь должно получиться удобно для пользователей.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines