Solved Blocked gui does not draw an qml item?
-
@PowerNow If you don't want to lock the GUI, you have to move heavyFunct() execution in another thread. There are no other option in my eyes.
To move the function execution to another thread, there a many way to do, but the easiest way for me is using QtConcurrent:
class MyClass: public QObject { Q_OBJECT ... private: void heavyFunct(); ... public: Q_INVOKABLE void doHeavyFnc() { if(!m_heavyInProgress.isRunning()) { QtConcurrent::run(this, &MyClass::heavyFunct); } } ... private: QFuture<void> m_heavyInProgress;
Hope this could help you.
-
Thxs to all of you!
But as I mentioned unfortunately I can't move at the moment the heavyFunct() (its a QFramebufferobject loaded via Loader which needs a lot of memory and power) into a separat threat, currently I'm looking for a simple solution.
@J.Hilk: Yes this works thxs! But It's an app using a Videoframbuffer (highest possible frame rate) and i think only for this button always check the frameSwapped signal does not make me feel good. Or is there a way to check it only once?I only want to visually show the user if he press on the button, that he have to wait and not press again during the loading of the heavyFunct(). Is there no way to force Qml to update the scenegraph and give response? The locking of the gui is not that problem.
-
@PowerNow said in Blocked gui does not draw an qml item?:
Or is there a way to check it only once?
make the slot connected to the frameSwapped signal disconnect itself when it gets called
-
@PowerNow I solved a similar issue by using a
Timer
. -
@PowerNow said in Blocked gui does not draw an qml item?:
(its a QFramebufferobject loaded via Loader
I'm not sure to understand how this works. Is the Loader a QML Loader instance?
Why is this loader not setasynchronous
to true?Loader { source: "myHeadyComponent.qml" asynchronous: true visible: status == Loader.Ready }
-
@KroMignon Hi, I just added asynchronous: true but surprisingly no change.
-
@PowerNow This sounds very strange to me. I often use
asynchronous
withLoader
, and it always works.Does your huge QML component also includes Loader?
-
@KroMignon The loaded Qml component "only" consists of a big QFramebufferObject which loads a lot of data in the graphiccard and this blocks the gui. Further Loader are not included.
-
@PowerNow Then you are either doing something wrong or using a non-threaded render loop. By default there is a dedicated render thread and a dedicated main GUI thread. Loading of data to the graphics card should happen in the render thread and won't block the GUI.
-
@Tom_H I tried it with a timer but it also does not work.
Timer { id: iTim interval: 0 running: false repeat: false triggeredOnStart: true onTriggered: { console.log("onTriggered"); iBut1.mTxt = "wait" } }
Without triggeredOnStart: true the triggerSignal is fired after the heavyFunct() is finished.
-
@Tom_H How can I found out that I'm using a non-threaded render loop? In the QQuickFrambufferObject I'm using of course the QQuickFramebufferObject::Renderer.
"Communication between the item and the renderer should primarily happen via the QQuickFramebufferObject::Renderer::synchronize() function. This function will be called on the render thread while the GUI thread is blocked."
It's still not clear how the gui and scene graph render works together. Based on the Qt arcticles it seems so that the scene graph render blocks the gui during rendering.
Is the gui blocked during upload of big Vertex/Index buffer objects?
-
For who is interessted, I handle the problem by using the pressed() signal.
MouseArea { property bool mRed: false onClicked: { heavyFunct(); mRed = false; } onPressed: { mRed = true; } onReleased: { mRed = false; } }