P
Pusher28 мая 2022 г. 8:48

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

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

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

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

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

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

12
o
  • 28 мая 2022 г. 13:00
  • (ред.)

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

    P
    • 28 мая 2022 г. 13:12
    • (ред.)

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

      o
      • 28 мая 2022 г. 17:11

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

        P
        • 29 мая 2022 г. 2:51
        • (ред.)

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

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

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

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

          o
          • 29 мая 2022 г. 15:49
          • (ред.)

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

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

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

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

            P
            • 29 мая 2022 г. 16:09

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

              o
              • 29 мая 2022 г. 16:37
              • Ответ был помечен как решение.

              ок

                P
                • 30 мая 2022 г. 12: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 г. 0:35

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

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

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

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

                    P
                    • 31 мая 2022 г. 2:46
                    1. "В диалоговом окне прогресс бар" - как происходит обновление/переисовка бара?

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

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

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

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

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

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

                      juvf
                      • 31 мая 2022 г. 3: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 г. 3:51

                        QCoreApplication::processEvents(QEventLoop::AllEvents);

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

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

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

                          Комментарии

                          Только авторизованные пользователи могут публиковать комментарии.
                          Пожалуйста, авторизуйтесь или зарегистрируйтесь
                          Дмитрий

                          C++ - Тест 004. Указатели, Массивы и Циклы

                          • Результат:60баллов,
                          • Очки рейтинга-1
                          Дмитрий

                          C++ - Тест 003. Условия и циклы

                          • Результат:92баллов,
                          • Очки рейтинга8
                          d
                          • dsfs
                          • 26 апреля 2024 г. 11:56

                          C++ - Тест 004. Указатели, Массивы и Циклы

                          • Результат:80баллов,
                          • Очки рейтинга4
                          Последние комментарии
                          k
                          kmssr9 февраля 2024 г. 2:43
                          Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                          АК
                          Анатолий Кононенко5 февраля 2024 г. 9:50
                          Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                          EVA
                          EVA25 декабря 2023 г. 18:30
                          Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
                          J
                          JonnyJo25 декабря 2023 г. 16:38
                          Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
                          G
                          Gvozdik19 декабря 2023 г. 5:01
                          Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
                          Сейчас обсуждают на форуме
                          G
                          George137 мая 2024 г. 7:27
                          добавить qlineseries в функции в функции: "GPlotter::addSeries(QString title, QVector &arr)" я вызываю метод setChart(...), я в конструктор передал адрес на QChartView элемент
                          BlinCT
                          BlinCT5 мая 2024 г. 12:46
                          Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
                          PS
                          Peter Son4 мая 2024 г. 0:57
                          Best Indian Food Restaurant In Cincinnati OH Ready to embark on a gastronomic journey like no other? Join us at App india restaurant and discover why we're renowned as the Best Indian Food Restaurant In Cincinnati OH . Whether y…
                          Evgenii Legotckoi
                          Evgenii Legotckoi2 мая 2024 г. 21:07
                          Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
                          IscanderChe
                          IscanderChe30 апреля 2024 г. 11:22
                          Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…

                          Следите за нами в социальных сетях