How to trigger QQuickItem.update() when worker thread finishes?
-
Man, I must be missing something stupidly simple here...
I’ve subclassed QuickFramebufferObject (call it “MyItem” and QQuickFrameBufferObject::Renderer (call it “MyRenderer”)The renderer launches a QThread worker, and also defines a slot called when that worker emits QThread::finished signal:
// Handle things when worker thread finishes connect(worker, &QThread::finished, this, &MyRenderer::mySlot, Qt::QueuedConnection);
From within mySlot() I want to trigger an update to item’s GUI, but calling MyItem::update() from the slot results in “Updates can only be scheduled from GUI thread or from QQuickItem::updatePaintNode()”. OK, but QQuickItem::updatePaintNode() specifies several arguments, and I have no idea how to supply these.
I thought that a slot called by QThread::finished() would run in the GUI thread - not true?
Isn’t there a simple way to just trigger an QQuickItem.update() when the worker thread is finished?Thanks!
-
@Tom-asso said in How to trigger QQuickItem.update() when worker thread finishes?:
Man, I must be missing something stupidly simple here...
I’ve subclassed QuickFramebufferObject (call it “MyItem” and QQuickFrameBufferObject::Renderer (call it “MyRenderer”)The renderer launches a QThread worker, and also defines a slot called when that worker emits QThread::finished signal:
// Handle things when worker thread finishes connect(worker, &QThread::finished, this, &MyRenderer::mySlot, Qt::QueuedConnection);
I haven't used QQuickFramebufferObject, but from a quick glance at the documentation:
On most platforms, the rendering will occur on a dedicated thread. For this reason, the QQuickFramebufferObject class enforces a strict separation between the item implementation and the FBO rendering. All item logic, such as properties and UI-related helper functions needed by QML should be located in a QQuickFramebufferObject class subclass. Everything that relates to rendering must be located in the QQuickFramebufferObject::Renderer class.
Connecting with a QueuedConnection (or AutoConnection in this case) to a Renderer object will result in the slot being called in the (potentially dedicated) renderer thread, which may not be the UI thread.
There's QQuickItem::update() and QQuickFramebufferObject::Renderer::update(). By any chance is the code calling the wrong one?
-
@jeremy_k wrote
There's QQuickItem::update() and QQuickFramebufferObject::Renderer::update(). By any chance is
the code calling the wrong one?Yes, that was exactly the problem; my renderer code called QQuickItem::update() . Instead it now calls QQuickFramebufferObject::Renderer::update(), and no more "Updates can only be scheduled from GUI thread" warning. Brilliant, thanks!