Search code examples
openglqt5qtopengl

QWidget::paintEngine being called from QCoreApplication::processEvents


I'm converting an OSX application from Qt 4/Carbon to Qt5.11 with the QOpenGLWidget.

I've moved the drawing "calls" to my overridden QOpenGlWidget::paintGL().

The problem is I'm still getting these messages on the console:

QWidget::paintEngine: Should no longer be called

Getting a stack trace, I've discovered that this is being called eventually from QCoreApplication::processEvents, which I'm calling from my own internal event loop.

Here's a stack trace (edited for readability)

  • thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    • frame #0: libQt5Widgets_debug.5.dylibQWidget::paintEngine() frame #1: libQt5Widgets_debug.5.dylibQOpenGLWidget::paintEngine(0) frame #2: libQt5Gui_debug.5.dylibQPainter::begin() frame #3: libQt5Gui_debug.5.dylibQPainter::QPainter() frame #4: libQt5Gui_debug.5.dylibQPainter::QPainter() frame #5: libQt5Widgets_debug.5.dylibQWidgetPrivate::drawWidget() frame #6: libQt5Widgets_debug.5.dylibQWidgetPrivate::repaint_sys() frame #7: libQt5Widgets_debug.5.dylibQWidgetPrivate::syncBackingStore() frame #8: libQt5Widgets_debug.5.dylibQWidgetWindow::handleExposeEvent() frame #9: libQt5Widgets_debug.5.dylibQWidgetWindow::event() frame #10: libQt5Widgets_debug.5.dylibQApplicationPrivate::notify_helper() frame #11: libQt5Widgets_debug.5.dylibQApplication::notify() frame #12: libQt5Core_debug.5.dylibQCoreApplication::notifyInternal2() frame #13: libQt5Gui_debug.5.dylibQCoreApplication::sendSpontaneousEvent() frame #14: libQt5Gui_debug.5.dylibQGuiApplicationPrivate::processExposeEvent() frame #15: libQt5Gui_debug.5.dylibQGuiApplicationPrivate::processWindowSystemEvent() frame #16: libQt5Gui_debug.5.dylibbool QWindowSystemInterfacePrivate::handleWindowSystemEvent<QWindowSystemInterface::SynchronousDelivery>() frame #17: libQt5Gui_debug.5.dylibvoid QWindowSystemInterface::handleExposeEvent() frame #18: libqcocoa_debug.dylibQCocoaWindow::handleExposeEvent() frame #19: libqcocoa_debug.dylib::-[QNSView updateRegion:](self=0x000061200039fc40, _cmd="updateRegion:", dirtyRegion=QRegion @ 0x00007ffeefbf9b18) frame #20: libqcocoa_debug.dylib::-[QNSView updateLayer](self=0x000061200039fc40, _cmd="updateLayer") frame #21: AppKit_NSViewUpdateLayer + 45 frame #22: AppKit-[_NSViewBackingLayer display] + 495 frame #23: QuartzCoreCA::Layer::display_if_needed(CA::Transaction*) + 634 frame #24: QuartzCoreCA::Context::commit_transaction(CA::Transaction*) + 319 frame #25: QuartzCoreCA::Transaction::commit() + 576 frame #26: QuartzCoreCA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 66 frame #27: CoreFoundationCFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 23 frame #28: CoreFoundation__CFRunLoopDoObservers + 452 frame #29: CoreFoundationCFRunLoopRunSpecific + 523 frame #30: HIToolboxRunCurrentEventLoopInMode + 293 frame #31: HIToolboxReceiveNextEventCommon + 618 frame #32: HIToolbox_BlockUntilNextEventMatchingListInModeWithFilter + 64 frame #33: AppKit_DPSNextEvent + 997 frame #34: AppKit-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1362 frame #35: libqcocoa_debug.dylibQCocoaEventDispatcher::processEvents(this=0x00006040000dbdf0, flags=(i = 0)) at qcocoaeventdispatcher.mm:482 frame #36: libQt5Core_debug.5.dylib`QCoreApplication::processEvents(flags=(i = 0)) at qcoreapplication.cpp:1252

The problem is that ::processEvents is eventually calling ::paintEngine for the QOpenGLWidget, OUTSIDE of ::paintGL, but it's totally out of my control.

FWIW, the Event driving this is a QEvent::UpdateRequest.

I tried overriding ::event in my QOpenGLWidget-inheriting class to call QOpenGlWidget::update when it receives a QEvent::UpdateRequest, but that just ended up making the app non-responsive.

How should I handle ::processEvents attempting to draw QOpenGlWidgets?

Thanks!


Solution

  • I fixed this by removing this statement from our QOpenGlWidget subclass:

    setAttribute( Qt::WA_PaintOnScreen, true );

    Removing this got ride of the paintEngine calls (and solved all kinds of other problems).