0

I am trying to implement busy indicator in my application. But the current implementation is not working correctly.

---Main.qml----
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2

ApplicationWindow {
    title: qsTr("Hello World")
    width: 640
    height: 480
    visible: true

BusyIndicator {
 id: indicator
 running: false
}

MainForm {
    anchors.fill: parent
    button1.onClicked: {
        indicator.running = true
        console.info(indicator.running)

        obj.runWorkerFunction()

        indicator.running=false
        console.info(indicator.running)
    }
}

}

---Testclass.cpp----

#include "testclass.h"
#include <QDebug>
#include <QThread>

TestClass::TestClass(QObject *parent) : QObject(parent)
{

}
TestClass::~TestClass(){
}

void TestClass::workerFunction() {
    for(int i = 0; i < 1000; i++){
            qDebug() << i;
    }
 qDebug() << "Done";
}

void TestClass:: runWorkerFunction(){
//    QThread* thread = QThread::create([this]() {
//                   workerFunction();
//                   emit workerFinished();
//                });
//    thread->start();
    workerFunction();
}

---Main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "testclass.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    TestClass obj;
    QQmlApplicationEngine engine;
    QQmlContext *context = engine.rootContext();
    context->setContextProperty("obj", &obj);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

I have tried using Thread which is currently commented out, but busy indicator does not work. The goal is to show the indicator only during the worker thread performs heavy calculation. Additionally with Connections binding I could not make it work. Can anyone help me out with this problem or provide some alternate solution.

Thank you

hunt
  • 1
  • 1
  • Where did you set your `classInstance` as QML context property in C++ ? – Mohammad Kanan Jul 12 '19 at 17:26
  • Possible duplicate of [How can I listen to a C++ signal from QML?](https://stackoverflow.com/questions/29995250/how-can-i-listen-to-a-c-signal-from-qml) – Mohammad Kanan Jul 12 '19 at 17:28
  • @MohammadKanan I set it in my main class, and i think it is not the problem because I had added messages to log and they were logging but were blocked and only after loading of file all messages were logged – hunt Jul 12 '19 at 18:12
  • @vinay provide a [MRE] – eyllanesc Jul 12 '19 at 18:30
  • @vinay I have not asked you for the code of your project, but an MRE, a code focused only on the current problem, if you want help then invest your time in **creating** it but your question is off-topic so it will probably close. – eyllanesc Jul 12 '19 at 18:51
  • Are you really in full control of your main `Event loop` .. ? – Mohammad Kanan Jul 12 '19 at 19:00
  • @eyllanesc: I have updated the code. Hopefully this should be sufficient – hunt Jul 12 '19 at 21:07
  • @MohammadKanan: I have updated the code. Now it must be much clear to understand the problem – hunt Jul 13 '19 at 14:33

1 Answers1

0

The problem when not using a thread is that the UI is actually blocked and the BusyIndicator cannot be updated. The problem should you be using a thread, the BusyIndicator gets set to running=false immediately after you fired the thread (and not waiting for it to finish).

You should make a property telling if the worker is working

(Note: untested! might have threading issues with the signals)

class TestClass {

    Q_PROPERTY(bool working MEMBER working_ NOTIFY workingChanged)

public:
    Q_INVOKABLE void workerFunction() {
        working_ = true;
        emit workingChanged();

        for(int i = 0; i < 1000; i++){
            qDebug() << i;
        }
        qDebug() << "Done";

        working_ = false;
        emit workingChanged();
    }

    ....
}

Then in QML, you can bind to this property:

BusyIndicator {
    id: indicator
    running: obj.working
}

Alternatively you can look into WorkerScript (Qml side) or QRunnable (C++ side)

Amfasis
  • 3,932
  • 2
  • 18
  • 27