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. Issue with QApplication::processEvents()

Issue with QApplication::processEvents()

Scheduled Pinned Locked Moved General and Desktop
15 Posts 5 Posters 19.0k 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.
  • A Offline
    A Offline
    alex.araratyan
    wrote on last edited by
    #1

    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
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      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
      0
      • A Offline
        A Offline
        alex.araratyan
        wrote on last edited by
        #3

        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
        0
        • JKSHJ Offline
          JKSHJ Offline
          JKSH
          Moderators
          wrote on last edited by
          #4

          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
          0
          • L Offline
            L Offline
            lgeyer
            wrote on last edited by
            #5

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

            1 Reply Last reply
            0
            • A Offline
              A Offline
              alex.araratyan
              wrote on last edited by
              #6

              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
              0
              • JKSHJ Offline
                JKSHJ Offline
                JKSH
                Moderators
                wrote on last edited by
                #7

                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
                0
                • T Offline
                  T Offline
                  terenty
                  wrote on last edited by
                  #8

                  [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
                  0
                  • A Offline
                    A Offline
                    alex.araratyan
                    wrote on last edited by
                    #9

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

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      alex.araratyan
                      wrote on last edited by
                      #10

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

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        alex.araratyan
                        wrote on last edited by
                        #11

                        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
                        0
                        • L Offline
                          L Offline
                          lgeyer
                          wrote on last edited by
                          #12

                          [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
                          0
                          • A Offline
                            A Offline
                            alex.araratyan
                            wrote on last edited by
                            #13

                            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
                            0
                            • A Offline
                              A Offline
                              alex.araratyan
                              wrote on last edited by
                              #14

                              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
                              0
                              • SGaistS Offline
                                SGaistS Offline
                                SGaist
                                Lifetime Qt Champion
                                wrote on last edited by
                                #15

                                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
                                0

                                • Login

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