BusyIndicator is not displayed

I want to show BusyIndicator while a long process is going on. The problem is that it does not appear when I start it and then shows when the process is complete. According to the docs

A busy indicator should be used to indicate activity while loading content or blocking a user interface that waits for a resource to become available.

I created a minimal code based on the source code

 Window { id: win width: 300 height: 300 property bool run : false Rectangle { anchors.fill: parent BusyIndicator { anchors.centerIn: parent running: run } MouseArea { anchors.fill: parent onClicked: { run = true for(var a=0;a<1000000;a++) { console.log(a) } run = false } } } } 

So, when the Rectangle button is pressed, I want to display the BusyIndicator for a while until the calculation is complete.

For example, I used the for loop here. In a real scenario, I call a function (which inserts about 1000 rows into the database) through ContextProperty . But in this case also BusyIndicator not displayed.

Am I doing it right? Or what would be the best way to do this?

+5
source share
3 answers

There is a way to do this using the QQuickWindow afterSynchronizing signal:

 import QtQuick 2.4 import QtQuick.Controls 1.3 ApplicationWindow { width: 400 height: 400 visible: true Component.onCompleted: print(Qt.formatDateTime(new Date(), "mm:ss:zzz"), "QML loaded") onAfterSynchronizing: { print(Qt.formatDateTime(new Date(), "mm:ss:zzz"), "Window content rendered") if (!loader.item) { loader.active = true } } Item { anchors.fill: parent BusyIndicator { running: !loader.item anchors.centerIn: parent } Loader { id: loader active: false anchors.fill: parent sourceComponent: Text { wrapMode: Text.Wrap Component.onCompleted: { for (var i = 0; i < 500; ++i) { text += "Hello, "; } } } } } } 

The idea is to use Loader to control when an expensive operation occurs. You can also use a dynamically loaded component via Qt.createQmlObject() or Qt.createComponent() to dynamically load the component into a separate file.

If you run this example, you will see that you get the following output:

qml: 58: 12: 356 loaded with QML
qml: 58: 12: 608 The contents of the window are displayed.

We use the QQuickWindow afterSynchronizing signal to know when the contents of the window are displayed and only act on it first (via if (!loader.item) ).

When the signal is initially emitted, we can be sure that the BusyIndicator started the animation, so the user will really see the turn icon.

As soon as Loader finishes loading the text, its item property will not be null, and the BusyIndicator will disappear.

+3
source

You cannot view your BusyIndicator just because a long operation in the onClicked handler blocks the graphical interface of the application and the indicator does not update. You must run such an operation on another thread to avoid freezing the GUI. A simple example:

QML

 Window { id: win width: 300 height: 300 property bool run : false Rectangle { anchors.fill: parent BusyIndicator { id: busy anchors.centerIn: parent running: win.run } MouseArea { anchors.fill: parent onClicked: { win.run = true thread.sendMessage({run : true}); } } WorkerScript { id: thread source: "handler.js" onMessage: { win.run = messageObject.run; } } } } 

handle.js

 WorkerScript.onMessage = function(message) { if(message.run === true) { for(var a=0;a<1000000;a++) { console.log(a) } } WorkerScript.sendMessage({run : false}); } 
+5
source

Launch the same issue today! I assume that you control your BusyIndicator from a C ++ property called busy . And you set busy to true just before your calculations and to false right after. Doing this resolved this for me. This is not a very elegant solution, but it works:

QML

 BusyIndicator { running: CPPModule.busy } 

CPP

 void CPPModule::setBusy(const bool &busy) { m_busy = busy; emit busyChanged(); } void CPPModule::InsertIntoDB() { setBusy(true); QThread::msleep(50); QCoreApplication::processEvents(); /* very Long Operation */ setBusy(false); } 
+1
source

Source: https://habr.com/ru/post/1208013/


All Articles