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. Signals from within the paint event -- crash?

Signals from within the paint event -- crash?

Scheduled Pinned Locked Moved General and Desktop
11 Posts 4 Posters 4.8k 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
    AllenMSaunders
    wrote on last edited by
    #1

    If I try to call the main window's status bar's "showMessage" function (directly or via propagated signals-slots) from within another widget's paint function (a QGraphicsItem, in this case), I get an access violation deep within the Qt code, somewhere under sendSpontaneousEvent.

    I can do this from other event handlers, e.g.: mouse hover. I can also cause an output message in an widget to be displayed ,but this occurs using an internal postEvent call within that widget.

    Is there something I'm fundamentally misunderstanding about events? I want to be able to update a data model structure from WITHIN the paint event (it's the most convenient place to perform a mouse position calculation) and have other widgets update (eventually) to reflect that change.

    Is this not possible?

    1 Reply Last reply
    0
    • A Offline
      A Offline
      AllenMSaunders
      wrote on last edited by
      #2

      On the off chance it is helpful to anyone, a sample of the call stack:

      Qt5Guid.dll!QRasterPaintEngine::transformChanged() Line 947 + 0x3 bytes C++
      Qt5Guid.dll!QPainterPrivate::updateMatrix() Line 663 C++
      Qt5Guid.dll!QPainter::setWorldTransform(const QTransform & matrix, bool combine) Line 8232 C++
      Qt5Widgetsd.dll!QGraphicsDropShadowEffect::draw(QPainter * painter) Line 1067 C++
      Qt5Widgetsd.dll!QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem * item, QPainter * painter, const QTransform * const viewTransform, QRegion * exposedRegion, QWidget * widget, double parentOpacity, const QTransform * const effectTransform) Line 4779 C++
      Qt5Widgetsd.dll!QGraphicsScenePrivate::drawItems(QPainter * painter, const QTransform * const viewTransform, QRegion * exposedRegion, QWidget * widget) Line 4667 + 0x3c bytes C++
      Qt5Widgetsd.dll!QGraphicsView::paintEvent(QPaintEvent * event) Line 3531 C++
      Qt5Widgetsd.dll!QWidget::event(QEvent * event) Line 8118 C++
      Qt5Widgetsd.dll!QFrame::event(QEvent * e) Line 534 + 0xc bytes C++
      Qt5Widgetsd.dll!QAbstractScrollArea::viewportEvent(QEvent * e) Line 1194 + 0xc bytes C++
      Qt5Widgetsd.dll!QGraphicsView::viewportEvent(QEvent * event) Line 2967 C++
      Qt5Widgetsd.dll!QAbstractScrollAreaPrivate::viewportEvent(QEvent * event) Line 110 + 0x28 bytes C++
      Qt5Widgetsd.dll!QAbstractScrollAreaFilter::eventFilter(QObject * o, QEvent * e) Line 126 + 0x29 bytes C++
      Qt5Cored.dll!QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject * receiver, QEvent * event) Line 1031 + 0x15 bytes C++
      Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3518 + 0x11 bytes C++
      Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3487 + 0x10 bytes C++
      Qt5Cored.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 935 + 0x15 bytes C++

      Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 240 + 0x38 bytes C++
      Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5157 + 0x11 bytes C++
      Qt5Widgetsd.dll!QWidgetBackingStore::doSync() Line 1183 C++
      Qt5Widgetsd.dll!QWidgetBackingStore::sync() Line 1030 C++
      Qt5Widgetsd.dll!QWidgetPrivate::syncBackingStore() Line 1693 C++
      Qt5Widgetsd.dll!QWidget::event(QEvent * event) Line 8256 C++
      Qt5Widgetsd.dll!QMainWindow::event(QEvent * event) Line 1497 C++
      Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3522 + 0x11 bytes C++
      Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3487 + 0x10 bytes C++
      Qt5Cored.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 935 + 0x15 bytes C++
      Qt5Cored.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 237 + 0x39 bytes C++
      Qt5Cored.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1539 + 0xd bytes C++
      Qt5Cored.dll!QCoreApplication::sendPostedEvents(QObject * receiver, int event_type) Line 1397 + 0x11 bytes C++
      Qt5Widgetsd.dll!QGraphicsViewPrivate::dispatchPendingUpdateRequests() Line 202 + 0x17 bytes C++
      Qt5Widgetsd.dll!QGraphicsScenePrivate::_q_processDirtyItems() Line 508 + 0x20 bytes C++
      Qt5Widgetsd.dll!QGraphicsScene::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int id, void * * a) Line 177 + 0xf bytes C++
      Qt5Cored.dll!QMetaCallEvent::placeMetaCall(QObject * object) Line 487 + 0x1d bytes C++
      Qt5Cored.dll!QObject::event(QEvent * e) Line 1242 C++
      Qt5Widgetsd.dll!QGraphicsScene::event(QEvent * event) Line 3478 + 0x10 bytes C++
      Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3522 + 0x11 bytes C++
      Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 2975 + 0x10 bytes C++
      Qt5Cored.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 935 + 0x15 bytes C++
      Qt5Cored.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 237 + 0x39 bytes C++
      Qt5Cored.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1539 + 0xd bytes C++
      Qt5Cored.dll!QCoreApplication::sendPostedEvents(QObject * receiver, int event_type) Line 1397 + 0x11 bytes C++
      qwindowsd.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 88 + 0xa bytes C++
      Qt5Cored.dll!qt_internal_proc(HWND
      * hwnd, unsigned int message, unsigned int wp, long lp) Line 423 C++

      1 Reply Last reply
      0
      • dheerendraD Offline
        dheerendraD Offline
        dheerendra
        Qt Champions 2022
        wrote on last edited by
        #3

        Is this multithreaded application ? Is this update happening across threads ?

        Dheerendra
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

        1 Reply Last reply
        0
        • A Offline
          A Offline
          AllenMSaunders
          wrote on last edited by
          #4

          It is not multithreaded, no.

          1 Reply Last reply
          0
          • N Offline
            N Offline
            NetZwerg
            wrote on last edited by
            #5

            Does the app still crash if there is no connection to that signal? If so your signal may result in a repaint wich emits a signal which results in a repaint which em.... (google rekursion)

            1 Reply Last reply
            0
            • JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by
              #6

              Hi, I don't know the exact mechanism of the crash, but try making the connection specifying Qt::QueuedConnection. That will delay the showMessage() call and hopefully avoid a crash.

              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
                AllenMSaunders
                wrote on last edited by
                #7

                The app will crash with or without a connected signal. What I mean is: if I directly call the member showMessage on the status bar (after confirming no stupid pointer mistakes or anything) it will crash in almost the exact manner as if I'd connected signal/slots from painted widget to the model and from the model to the main window (which would then update the status bar).

                I can make the same calls (or signals) safely from other event handles (e.g.: mouse move) but NOT from within the paint event handler.

                I can re-design architecture around this, but I'm mostly concerned that I don't understand why it's happening, and I'm concerned I will run into other issues if I don't understand the limitations on being in the paint event (or similar?) context.

                1 Reply Last reply
                0
                • N Offline
                  N Offline
                  NetZwerg
                  wrote on last edited by
                  #8

                  Would you mind sharing the code? It should not happen anything by only emitting a signal in the paintEvent() method.

                  1 Reply Last reply
                  0
                  • JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on last edited by
                    #9

                    [quote author="AllenMSaunders" date="1406812060"]The app will crash with or without a connected signal. What I mean is: if I directly call the member showMessage on the status bar (after confirming no stupid pointer mistakes or anything) it will crash in almost the exact manner as if I'd connected signal/slots from painted widget to the model and from the model to the main window (which would then update the status bar).[/quote]That's because, when you use a Direct Connection, emitting a signal to run a slot is the same as directly calling the slot.

                    That's why I suggested trying a Queued Connection.

                    [quote author="NetZwerg" date="1406812601"]Would you mind sharing the code? It should not happen anything by only emitting a signal in the paintEvent() method.[/quote]
                    EDIT: Oops, I thought AllenMSaunde wrote the line above. That's why my original reply below sounds odd.

                    Sure. Just add "Qt::QueuedConnection" to the end of your existing connection:
                    @
                    connect(this, SIGNAL(mySignal(QString)),
                    statusBar, SLOT(showMessage(QString)),
                    Qt::QueuedConnection);
                    @

                    I agree that it shouldn't happen, and I don't think you've misunderstood something. The reality is that Qt is a huge and complex framework so there will be bugs.

                    I suspect that, somewhere deep inside Qt's code, something falls over when you interrupt the current paint event with an action that will also update your GUI's display. In your case, showMessage() interrupts the current paint event.

                    If this indeed is the source of the bug, then using a Queued Connection is a workaround for the crash, as it waits for the current paint event to finish first, before updating the status bar.

                    If that does eliminate the crash, you can bring this to the attention of Qt engineers by reporting it to https://bugreports.qt-project.org/

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

                    1 Reply Last reply
                    0
                    • dheerendraD Offline
                      dheerendraD Offline
                      dheerendra
                      Qt Champions 2022
                      wrote on last edited by
                      #10

                      Also very keen to make this happen. How about sharing simple sample code so that we can see the same ?

                      Dheerendra
                      @Community Service
                      Certified Qt Specialist
                      http://www.pthinks.com

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        AllenMSaunders
                        wrote on last edited by
                        #11

                        The code is pretty large and the relevant components are scattered.

                        When I get a chance I'll try to trim it down to the minimum components that produce the behavior.

                        Thanks all for the responses so far.

                        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