P
Мамыр 28, 2022, 6:48 Т.Қ.

Как очичтисть очередь событий для конпки

В программе есть длительная операция (может достигать 50 сек.).
Во время этой операции вызываю Dialog{ modal: true }. В диалоговом окне прогресс бар и кнопка закрытия окна,
у которой enabled: false. По окончанию операции кнопке закрытия ставлю enabled: true.

Если во время дляительной операции нажать кнопку закрытия на диалоговом окне,а потом любую другую кнопку или объект в главном окне программы, то после окончания операции, как только ставлю кнопеке enabled: true, диалоговое окно закрывается и происходит обработка остальных нажатий. Т.е. получается, что события накапливаются в очереди и обрабатываются позже.

Собственно вопрос, как очисть события для кнопки до установки enabled: true?

Upd. пробовал QCoreApplication::removePostedEvents(nullptr) эффекта нет.

3

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

12
o
  • Мамыр 28, 2022, 11 Т.Қ.
  • (өңделген)

не нужно очишать очередь, нужно, писать приложение многопоточным через qthread или qconcurrent

    P
    • Мамыр 28, 2022, 11:12 Т.Қ.
    • (өңделген)

    Каким образом открыть модальное диалоговое окноно в QML из другого потока?
    Не понимаю, зачем в данном случае многопоточность, нужно просто, чтобы кнопка, когда она не активна не принимала события.

      o
      • Мамыр 29, 2022, 3:11 Т.Ж.

      нужно сделать связку qml и c++, тяжелые задачи отправляются на обработку в с++, в qml остаются только быстрые.
      и у кнопок есть свойство
      enabled: true\false
      при запуске\остановке задачи нужно задать соответсвующее занчение этого параметра.

        P
        • Мамыр 29, 2022, 12:51 Т.Қ.
        • (өңделген)

        нужно сделать связку qml и c++, тяжелые задачи отправляются на обработку в с++, в qml остаются только быстрые

        на QML только QUI, остальное в C++, что нужно выведено в отдельный поток, при чем тут это?

        и у кнопок есть свойство enabled: true\false при запуске\остановке задачи нужно задать соответсвующее занчение этого параметра.

        После установки у кнопки enabled: true происходит обработка нажатия, которое блыо сделано пока кнопка была неактивна (enabled: false), закрывается диалоговое окно и обрабатываются остальные нажатия, причем все, которые сделал.

          o
          • Мамыр 30, 2022, 1:49 Т.Ж.
          • (өңделген)

          на QML только QUI, остальное в C++, что нужно выведено в отдельный поток, при чем тут это?

          явно, что-то идет не так.

          enabled: true происходит обработка нажатия, которое блыо сделано пока кнопка была неактивна (enabled: false),

          этого не может быть.
          хорошо бы предявить исходный код.

            P
            • Мамыр 30, 2022, 2:09 Т.Ж.

            Я думал, что сигналы к неактивным эффектам должны отбрасываться, а не копиться в очереди.
            Попробую на досуге сделать минимальный тестовый проэкт.

              o
              • Мамыр 30, 2022, 2:37 Т.Ж.
              • Жауап шешім ретінде белгіленді.

              ок

                P
                • Мамыр 30, 2022, 10:04 Т.Қ.

                Тестовый проект сделал, но на нем все работает нормально.

                Причину нашел, во время операции есть функция ожидания, в короторой такой код:

                    static QEventLoop loop;
                    static QTimer timer;
                
                    connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
                    connect(this, &Writer::recivedMidiMessage, &loop, &QEventLoop::quit);
                
                    timer.setSingleShot(true);
                    timer.start(waitMs);
                    loop.exec(QEventLoop::ExcludeUserInputEvents);
                

                ost.vld - спасибо за помощь

                  juvf
                  • Мамыр 31, 2022, 10:35 Т.Ж.

                  читаю с первого поста.... ни чего не понятно.... это конечно хорошо, что у вас проблема решилась. Но....
                  1. "В программе есть длительная операция (может достигать 50 сек.). Во время этой операции вызываю Dialog{ modal: true }." - т.е. эта длительная операция выполняется в gui потоке?

                  1. "В диалоговом окне прогресс бар" - как происходит обновление/переисовка бара?

                  2. "кнопка закрытия окна, у которой enabled: false" + "Если во время дляительной операции нажать кнопку закрытия" - а как такое возможно? Как можно даже теоретически нажать дизейбленную кнопку? Что такое "нажать кнопку"? Есть разные способы (мышкой, клавиатурой, палец+тачскрин, ....) - "нажать кнопку" (будем считать, что кнопка без фиксации) - это значит передать ей фокус, перевести её в состояние "нажатая" и перевести её в состояние "отжатая" - вот тогда это будет считаться "нажали кнопку". Как вы умудрились задезейбленую кнопку перевести в состояние "нажатая"? Может всё таки вы не "нажали кнопку", а кликнули мышкой по неактивной кнопке?

                  3. ..... ещё есть вопросы конечно.... взглянуть бы на исходный код. Вам бы быстрее помогли, на и вопросов бы было мнеьше.

                    P
                    • Мамыр 31, 2022, 12:46 Т.Қ.
                    1. "В диалоговом окне прогресс бар" - как происходит обновление/переисовка бара?

                    По сигналу прогрессбар обновляется.

                    1. кнопка закрытия окна, у которой enabled: false" + "Если во время дляительной операции нажать кнопку закрытия" - а как такое возможно? Как можно даже теоретически нажать дизейбленную кнопку? Что такое "нажать кнопку"? Есть разные способы (мышкой, клавиатурой, палец+тачскрин, ....) - "нажать кнопку" (будем считать, что кнопка без фиксации) - это значит передать ей фокус, перевести её в состояние "нажатая" и перевести её в состояние "отжатая" - вот тогда это будет считаться "нажали кнопку". Как вы умудрились задезейбленую кнопку перевести в состояние "нажатая"? Может всё таки вы не "нажали кнопку", а кликнули мышкой по неактивной кнопке?

                    Кнопка прорисована, но не активна, нажимаешь мышкой, естественно ничего не происходит.
                    Но как только ставишь enabled: true, то происходит обработка нажатия

                    1. ..... ещё есть вопросы конечно.... взглянуть бы на исходный код. Вам бы быстрее помогли, на и вопросов бы было мнеьше.

                    Весь проект скинуть не могу, поэтому так, изначально подумал, что поведение штатное и есть решение.
                    Оказалось, что побочный эффект.

                    Длительная операция, прошивка устройства, протокол обмена продиктован устройством, повлиять на него никак не могу.
                    Данные передаются пакетами по 2 КБ, потом от устройства приходит ответ, что все получено и т.д.
                    Ответ приходит через callback, поэтому и нужна функция ожидания: или пришел ответ и данные передаются дальше, или ответа нет и передача данных прерывается. Собственно во время ожидания и запускал loop.exec(QEventLoop::ExcludeUserInputEvents);
                    Перепишу все на сигналах с таймером.

                      juvf
                      • Мамыр 31, 2022, 1:16 Т.Қ.

                      я делал подобные задачи... чтоб не возиться с потоками - всю передачу вел в потоке GUI. т.е. по кнопке "Burn" вызывался слот и прямо в слоте дизаблил виджеты, в цыкле делал прошивку (отправку и прием данных) и задавал значения прогрессБару, после цыкла енаблел виджеты. Естественно если так сделать, то гуи не перерисуется до выхода из слота. И все клики по кнопкам накопятся и отработаются после прошивки. Чтобы не копились события, чтобы во время длительной операции перерисовавался прогресс и перерисовывались (дазабле/енабле) кнопки и виджеты, в цыкле отправки/ожидания данных нужно переодически вызывать

                      QCoreApplication::processEvents(QEventLoop::AllEvents);

                      Да, может не совсем хороший способ в GUI потоке делать медленную переправку данных, но для мелких поделок разводить кучу дополнительных потоков и переплетение их сигналами/слотами, да ещё и таймера - это оверинженеринг. А так, можно по быстрому что-то простое сделать. Визуально это будет выглядеть как "работа GUI" в своем потоке, "примем/отправка данных" в своем потоке.

                      void MyProg::burn() //slot
                      {
                          burnBut->setEnable(false);
                          cancelBut->setEnable(false);
                          stopBut->setEnable(true);
                          progress->setEnable(true);
                          progress->setValue(true);
                          QCoreApplication::processEvents(QEventLoop::AllEvents);
                          while(какойнить флаг готовности)
                          {
                              //длительная процедура
                      
                              /*
                              * тут быстрая отправка
                              */
                      
                              QCoreApplication::processEvents(QEventLoop::AllEvents);
                              if(stopBut->wasClicked)
                                  break;
                              progress->setValue(newValue);
                              QCoreApplication::processEvents(QEventLoop::AllEvents);
                              sleep(10); // если нет ожиданий коротких в while, то можно слыпом подстраховаться.  
                          }
                          burnBut->setEnable(true);
                          cancelBut->setEnable(true);
                          stopBut->setEnable(false);
                          progress->setEnable(false);
                          QCoreApplication::processEvents(QEventLoop::AllEvents);//тут не обязательно. 
                      }
                      
                        P
                        • Мамыр 31, 2022, 1:51 Т.Қ.

                        QCoreApplication::processEvents(QEventLoop::AllEvents);

                        вот это надо протестировать

                        Да, может не совсем хороший способ в GUI потоке делать медленную переправку данных, но для мелких поделок разводить кучу дополнительных потоков и переплетение их сигналами/слотами, да ещё и таймера - это оверинженеринг. А так, можно по быстрому что-то простое сделать. Визуально это будет выглядеть как "работа GUI" в своем потоке, "примем/отправка данных" в своем потоке.

                        Тут согласен, в моем случае во время записи, кроме самой записи только перерисовка GUI и нужна.

                          Пікірлер

                          Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
                          Кіріңіз немесе Тіркеліңіз