Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Issue with QApplication::processEvents()

    General and Desktop
    5
    15
    17853
    Loading More Posts
    • 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.
    • A
      alex.araratyan last edited by

      The following code segfault with Qt 4.7.2. It looks to be a Qt bug. Any idea?
      @
      #include <QApplication>
      #include <QMainWindow>
      #include <QResizeEvent>
      #include <QWidget>

      class View: public QWidget
      {
      public:
      View(QWidget *parent): QWidget(parent) {};

      void resizeEvent(QResizeEvent*) {
          for (unsigned iv = 0; iv < 500; ++iv)
              qApp->processEvents();
      }
      

      };

      int main(int argc, char** argv){
      QApplication app(argc,argv);
      QMainWindow mainWindow;
      View view(&mainWindow);

      mainWindow.setCentralWidget(&view);
      mainWindow.show();
      
      return (app.exec&#40;&#41;&#41;;
      

      }
      @

      1 Reply Last reply Reply Quote 0
      • JKSH
        JKSH Moderators last edited by

        If you call processEvents() inside an event handler, you're at risk of infinite recursion -- processEvents() calls resizeEvent(), resizeEvent() calls processEvents(), processEvents() calls resizeEvent() again, and so on

        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

        1 Reply Last reply Reply Quote 0
        • A
          alex.araratyan last edited by

          Thanks for the reply. I printed out calls and found out that this is not the case: no recursive calls processEvents <-> resize event were detected. Also the code properly worked with the older versions of Qt. If it's prohibited now I think it should have been documented.

          1 Reply Last reply Reply Quote 0
          • JKSH
            JKSH Moderators last edited by

            Where does the segfault occur?

            Try allocating your View on the heap instead of on the stack. When QWidgets (and QObjects in general) are destroyed, they will destroy their children too. So, when the QMainWindow goes out of scope, it may try to delete your View -- causing it to be destroyed twice. I'm not 100% sure though.

            Qt/C++ does not explicitly prohibit you from calling processEvents() within event handlers, but it is considered a dangerous practice.

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            1 Reply Last reply Reply Quote 0
            • L
              lgeyer last edited by

              Why do you want to call processEvents() inside an event handler in the first place?

              1 Reply Last reply Reply Quote 0
              • A
                alex.araratyan last edited by

                let me explain. There is a very long drawing opration in the application. To make it more user responsive processEvents is called from the drawing loop to process other events like resizi event. So whenever application window is resized during the draw, resize event hadler is being called it starts drawing over again for the resized window. The sample I provided here is just a simplified model which reproduces the issue.

                1 Reply Last reply Reply Quote 0
                • JKSH
                  JKSH Moderators last edited by

                  Does the segfault still occur if you allocate the View on the heap? (i.e. use new to create it)

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  1 Reply Last reply Reply Quote 0
                  • T
                    terenty last edited by

                    [quote author="alex.araratyan" date="1356166469"]let me explain. There is a very long drawing opration in the application. To make it more user responsive processEvents is called from the drawing loop to process other events like resizi event. So whenever application window is resized during the draw, resize event hadler is being called it starts drawing over again for the resized window. The sample I provided here is just a simplified model which reproduces the issue. [/quote]
                    In the case you described processEvents would not be called from inside an event handler I think

                    1 Reply Last reply Reply Quote 0
                    • A
                      alex.araratyan last edited by

                      It will be called, because resize event handler calls the same drawing procedure which calls processEvents in its turn.

                      1 Reply Last reply Reply Quote 0
                      • A
                        alex.araratyan last edited by

                        Segfault stil occurs when Views is allocated on the heap :-(

                        1 Reply Last reply Reply Quote 0
                        • A
                          alex.araratyan last edited by

                          And here is the stack trace print out at the point of segfault, which happens upon window resizing:

                          (gdb) bt
                          #0 0x08751c9b in QVariantAnimationPrivate::valueAt(double) const ()
                          #1 0x08751d93 in QVariantAnimation::keyValueAt(double) const ()
                          #2 0x08751e1f in QVariantAnimation::startValue() const ()
                          #3 0x08754b64 in QPropertyAnimation::updateState(QAbstractAnimation::State, QAbstractAnimation::State) ()
                          #4 0x0874f92b in QAbstractAnimationPrivate::setState(QAbstractAnimation::State) ()
                          #5 0x08750187 in QAbstractAnimation::start(QAbstractAnimation::DeletionPolicy) ()
                          #6 0x0845e3f0 in QWidgetAnimator::animate(QWidget*, QRect const&, bool) ()
                          #7 0x086ce622 in QDockAreaLayout::apply(bool) ()
                          #8 0x08401772 in QMainWindowLayoutState::apply(bool) ()
                          #9 0x08405f35 in QMainWindowLayout::applyState(QMainWindowLayoutState&, bool) ()
                          #10 0x0840662b in QMainWindowLayout::setGeometry(QRect const&) ()
                          #11 0x08096e3f in QLayoutPrivate::doResize(QSize const&) ()
                          #12 0x0809831c in QLayout::widgetEvent(QEvent*) ()
                          #13 0x08078bfd in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
                          #14 0x0807dc94 in QApplication::notify(QObject*, QEvent*) ()
                          #15 0x088329cb in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
                          #16 0x080d574d in QETWidget::translateConfigEvent(_XEvent const*) ()
                          #17 0x080e4fb8 in QApplication::x11ProcessEvent(_XEvent*) ()
                          #18 0x0810bedb in QEventDispatcherX11::processEvents(QFlagsQEventLoop::ProcessEventsFlag) ()
                          #19 0x08831c09 in QEventLoop::processEvents(QFlagsQEventLoop::ProcessEventsFlag) ()
                          #20 0x08831eaa in QEventLoop::exec(QFlagsQEventLoop::ProcessEventsFlag) ()
                          #21 0x088366cf in QCoreApplication::exec() ()
                          #22 0x08076c37 in QApplication::exec() ()
                          #23 0x080756ea in main (argc=2, argv=0xffff8224) at gdsview.cc:25

                          1 Reply Last reply Reply Quote 0
                          • L
                            lgeyer last edited by

                            [quote author="alex.araratyan" date="1356166469"]let me explain. There is a very long drawing opration in the application. To make it more user responsive processEvents is called from the drawing loop to process other events like resizi event. So whenever application window is resized during the draw, resize event hadler is being called it starts drawing over again for the resized window. The sample I provided here is just a simplified model which rproduces the issue. [/quote]

                            The rule of thumb is: if the the drawing can't be done in time, it doesn't belong into <code>paintEvent()</code>. This includes the necessity of processEvents().

                            The usual solution is that drawing is not done directly to the widget surface, but rather to a QPixmap, which is then drawn to the widget surface in <code>paintEvent()</code> using for instance <code>QPainter::drawPixmap()</code>.

                            This has several advantages:

                            • the <code>paintEvent()</code> is quite fast,
                            • the widget content is only drawn when it has to be (the underlying data has changed); otherwise the cached QPixmap is used (for example during resize),
                            • the widget content can be drawn in a secondary thread and thus no longer blocks the main thread.

                            For an example see "C++ GUI Programming with Qt4 - Double Buffering":http://www.informit.com/articles/article.aspx?p=1405227&seqNum=4.

                            If you are out for advice invest your time in implementing a proper drawing strategy instead. The necessity of re-entering the event loop, especially in an event handler, is more often then not a clear indicator for a questionable design choice, and even if you solve the problem now, it might turn on you again later.

                            If you still think this is caused by undefined behaviour on the part of Qt please feel free to file a "bug report":https://bugreports.qt-project.org.

                            1 Reply Last reply Reply Quote 0
                            • A
                              alex.araratyan last edited by

                              What currently is implemented is the following:

                              • there are two QPixmap off-screen surfaces
                              • one of them is used for actual drawing which sometimes takes long time
                              • by the end of drawing the content of the first QPixmap copied to the second one
                              • QPaintEvent used to render the content of the second one to the actual screen - QCanvas
                              • processEvents is used during drawing loop when drawing on the first QPixmap in order to quickly react to the user events like resize or zoom without waiting for the entire drawing. Then if during drawing resize event is processed its handler starts drawing again which leads to the situation when processEvent is being called from the event handler (resizeEvent).

                              So, if this is not good then the only way I can see is to perform drawing in the thread. But as I learned from Qt reference QPixmap cannot be used from the thread and QImage should be used instead. On the other hand Qt reference recommends QPixmap of off-screen drawing. So what is the solution of this contradiction?

                              1 Reply Last reply Reply Quote 0
                              • A
                                alex.araratyan last edited by

                                After some more research now I realize that the application should be redesigned to implement drawing in non-gui thread and to use drawing on QImage instead of QPixmap. But when redesigning application to use non-gui thread for drawing it appears that we can’t use QBrush::setTexture(QPixmap) method any more, since QPixmap can’t be used from non-gui thread. Any idea how we can use pattern based brush for non-gui thread drawing?

                                1 Reply Last reply Reply Quote 0
                                • SGaist
                                  SGaist Lifetime Qt Champion last edited by

                                  Hi,

                                  I didn't tried it but wouldn't be "setTextureImage":http://qt-project.org/doc/qt-4.8/qbrush.html#setTextureImage an alternative ?

                                  Interested in AI ? www.idiap.ch
                                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                  1 Reply Last reply Reply Quote 0
                                  • First post
                                    Last post