Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QPushButton cannot be released
Forum Updated to NodeBB v4.3 + New Features

QPushButton cannot be released

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 3 Posters 561 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    MoonBrid
    wrote on last edited by
    #1

    I did a time-consuming operation in the button_1 slot function. In order to avoid the interface losing response, use QApplication: : processEvents (). However, if the button_2 is keep pressed during the while(time.elapsed() < 2000), the button_2 cannot be released after the while is over.
    Note: There is no problem with the way you use the mouse to click, but there is a problem with the way you use the touch.

    This is the cpp file:

    #include "widget.h"
    #include <QTime>
    #include <QPushButton>
    #include <QApplication>
    #include <QDebug>
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        button_1 = new QPushButton("QPushButton 1", this);
        button_2 = new QPushButton("QPushButton 2", this);
        button_1->setGeometry(50, 100, 200, 200);
        button_2->setGeometry(300, 100, 200, 200);
        resize(600, 400);
        connect(button_1, &QPushButton::clicked, this, &Widget::pushButton1Click);
    }
    
    Widget::~Widget()
    {
    
    }
    
    void Widget::pushButton1Click()
    {
        qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<< "";
    
        QTime time;
        time.start();
        while(time.elapsed() < 2000)
            QApplication::processEvents();
    
        qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<< "";
    }
    

    This is the header file:

    #ifndef WIDGET_H
    #define WIDGET_H
    #include <QWidget>
    class QPushButton;
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();
    
    private:
        QPushButton *button_1;
        QPushButton *button_2;
    
    private slots:
        void pushButton1Click();
    };
    #endif // WIDGET_H
    

    This is the result of the run:
    edc882cd-7cec-449b-a0ee-8c1611343d91-image.png

    JonBJ 1 Reply Last reply
    0
    • M MoonBrid

      @JonB If I don't use processEvents(), that causes another problem. The program will block in the while loop, and the interface will become unresponsive, unable to press the button_2.

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #9

      @MoonBrid again: fix your design and don't block the main event loop. Do heavy computing stuff in separate threads.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      1
      • M MoonBrid

        I did a time-consuming operation in the button_1 slot function. In order to avoid the interface losing response, use QApplication: : processEvents (). However, if the button_2 is keep pressed during the while(time.elapsed() < 2000), the button_2 cannot be released after the while is over.
        Note: There is no problem with the way you use the mouse to click, but there is a problem with the way you use the touch.

        This is the cpp file:

        #include "widget.h"
        #include <QTime>
        #include <QPushButton>
        #include <QApplication>
        #include <QDebug>
        
        Widget::Widget(QWidget *parent)
            : QWidget(parent)
        {
            button_1 = new QPushButton("QPushButton 1", this);
            button_2 = new QPushButton("QPushButton 2", this);
            button_1->setGeometry(50, 100, 200, 200);
            button_2->setGeometry(300, 100, 200, 200);
            resize(600, 400);
            connect(button_1, &QPushButton::clicked, this, &Widget::pushButton1Click);
        }
        
        Widget::~Widget()
        {
        
        }
        
        void Widget::pushButton1Click()
        {
            qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<< "";
        
            QTime time;
            time.start();
            while(time.elapsed() < 2000)
                QApplication::processEvents();
        
            qDebug()<<__FILE__<<__FUNCTION__<<__LINE__<< "";
        }
        

        This is the header file:

        #ifndef WIDGET_H
        #define WIDGET_H
        #include <QWidget>
        class QPushButton;
        class Widget : public QWidget
        {
            Q_OBJECT
        
        public:
            Widget(QWidget *parent = nullptr);
            ~Widget();
        
        private:
            QPushButton *button_1;
            QPushButton *button_2;
        
        private slots:
            void pushButton1Click();
        };
        #endif // WIDGET_H
        

        This is the result of the run:
        edc882cd-7cec-449b-a0ee-8c1611343d91-image.png

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #2

        @MoonBrid said in QPushButton cannot be released:

        while(time.elapsed() < 2000)
            QApplication::processEvents();
        

        This is way too busy a loop. Put in a reasonable test or try calling processEvents() much less often, e.g. if (time.elapsed() % 100 == 0), and see if that helps.

        Calling processEvents() because you are doing a "busy" calculation and want to "avoid the interface losing response," is evil and a bad pattern. If this is ultimately the problem (or you want to write better Qt code) change over to a proper pattern, like doing limited "chunks" of work over time from a QTimer or use a worker thread.

        Qt does have a concept of different, "nested" event loops. Your processEvents() is not at the same "level" as the base event loop processor. It is possible that something about button release needs to be processed at the same level as the button press. I am not sure about this, and whether it applies to your case, but it could be a factor.

        M 1 Reply Last reply
        1
        • JonBJ JonB

          @MoonBrid said in QPushButton cannot be released:

          while(time.elapsed() < 2000)
              QApplication::processEvents();
          

          This is way too busy a loop. Put in a reasonable test or try calling processEvents() much less often, e.g. if (time.elapsed() % 100 == 0), and see if that helps.

          Calling processEvents() because you are doing a "busy" calculation and want to "avoid the interface losing response," is evil and a bad pattern. If this is ultimately the problem (or you want to write better Qt code) change over to a proper pattern, like doing limited "chunks" of work over time from a QTimer or use a worker thread.

          Qt does have a concept of different, "nested" event loops. Your processEvents() is not at the same "level" as the base event loop processor. It is possible that something about button release needs to be processed at the same level as the button press. I am not sure about this, and whether it applies to your case, but it could be a factor.

          M Offline
          M Offline
          MoonBrid
          wrote on last edited by
          #3

          @JonB Thank you for your reply. I tried if (time.elapsed() % 100 == 0) and if (time.elapsed() % 1000 == 0), but it didn't work.

          From the source:”src/gui/kernel/qguiapplication.cpp“

          void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e)
          {
          ...
                  switch (touchPoint.state()) {
                  ...
                  case Qt::TouchPointReleased:
                      w = touchInfo.window;
                      ///< test remove
          //            if (!w)
          //                continue; 
                      ///< test add
                      if (!w) {
                          // determine which window this event will go to
                          if (!window)
                              window = QGuiApplication::topLevelAt(touchPoint.screenPos().toPoint());
                          if (!window)
                              continue;
                          w = window;
                      }
                      ...
              }
              ...
              if (windowsNeedingEvents.isEmpty())
                  return;
          ...
          }
          

          This is because the windowsNeedingEvents. IsEmpty , so it return. And my test code can solve my problem. But I don't want to change the source code for fear of causing other problems.

          JonBJ 1 Reply Last reply
          0
          • M MoonBrid

            @JonB Thank you for your reply. I tried if (time.elapsed() % 100 == 0) and if (time.elapsed() % 1000 == 0), but it didn't work.

            From the source:”src/gui/kernel/qguiapplication.cpp“

            void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::TouchEvent *e)
            {
            ...
                    switch (touchPoint.state()) {
                    ...
                    case Qt::TouchPointReleased:
                        w = touchInfo.window;
                        ///< test remove
            //            if (!w)
            //                continue; 
                        ///< test add
                        if (!w) {
                            // determine which window this event will go to
                            if (!window)
                                window = QGuiApplication::topLevelAt(touchPoint.screenPos().toPoint());
                            if (!window)
                                continue;
                            w = window;
                        }
                        ...
                }
                ...
                if (windowsNeedingEvents.isEmpty())
                    return;
            ...
            }
            

            This is because the windowsNeedingEvents. IsEmpty , so it return. And my test code can solve my problem. But I don't want to change the source code for fear of causing other problems.

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by
            #4

            @MoonBrid
            Are you saying there is a problem because you call processEvents(), or are you saying it never works? If the former, so did you try getting rid of processEvents() as suggested?

            M 1 Reply Last reply
            0
            • JonBJ JonB

              @MoonBrid
              Are you saying there is a problem because you call processEvents(), or are you saying it never works? If the former, so did you try getting rid of processEvents() as suggested?

              M Offline
              M Offline
              MoonBrid
              wrote on last edited by
              #5

              @JonB processEvents() is working normally, durind the while , I can press button_2.For some reason, I can't give up using processEvent().And the mouse doesn't have this problem, but the touch does, whether it's a bug?

              Christian EhrlicherC JonBJ 2 Replies Last reply
              0
              • M MoonBrid

                @JonB processEvents() is working normally, durind the while , I can press button_2.For some reason, I can't give up using processEvent().And the mouse doesn't have this problem, but the touch does, whether it's a bug?

                Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #6

                @MoonBrid said in QPushButton cannot be released:

                For some reason, I can't give up using processEvent()

                Fix your design. You already found out the reason. Noone will change this.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                0
                • M MoonBrid

                  @JonB processEvents() is working normally, durind the while , I can press button_2.For some reason, I can't give up using processEvent().And the mouse doesn't have this problem, but the touch does, whether it's a bug?

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #7

                  @MoonBrid said in QPushButton cannot be released:

                  I can't give up using processEvent()

                  The question was, if you do not do processEvents() does it then work or still go wrong?

                  M 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @MoonBrid said in QPushButton cannot be released:

                    I can't give up using processEvent()

                    The question was, if you do not do processEvents() does it then work or still go wrong?

                    M Offline
                    M Offline
                    MoonBrid
                    wrote on last edited by
                    #8

                    @JonB If I don't use processEvents(), that causes another problem. The program will block in the while loop, and the interface will become unresponsive, unable to press the button_2.

                    Christian EhrlicherC JonBJ 2 Replies Last reply
                    0
                    • M MoonBrid

                      @JonB If I don't use processEvents(), that causes another problem. The program will block in the while loop, and the interface will become unresponsive, unable to press the button_2.

                      Christian EhrlicherC Offline
                      Christian EhrlicherC Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      @MoonBrid again: fix your design and don't block the main event loop. Do heavy computing stuff in separate threads.

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      1 Reply Last reply
                      1
                      • M MoonBrid

                        @JonB If I don't use processEvents(), that causes another problem. The program will block in the while loop, and the interface will become unresponsive, unable to press the button_2.

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by JonB
                        #10

                        @MoonBrid said in QPushButton cannot be released:

                        @JonB If I don't use processEvents(), that causes another problem. The program will block in the while loop, and the interface will become unresponsive, unable to press the button_2.

                        Sorry, I give up. That is not what I asked you. I have asked/suggested more than once that you remove the processEvents() and then tell us whether the behaviour of holding the button down during the 2 seconds and then releasing it afterwards does or does not recognise the button up. That is all you had to try. I don't understand why it's so difficult to try something while you diagnose. No more from me now.

                        1 Reply Last reply
                        1
                        • M MoonBrid has marked this topic as solved on

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved