如何在Qml / C ++中实现忙碌指示器?

时间:2019-07-12 17:02:33

标签: multithreading qt qml qtquick2 qthread

我正在尝试在我的应用程序中实现繁忙指示器。但是当前的实现无法正常工作。

---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();
}

我尝试使用当前已被注释掉的线程,但是繁忙指示器不起作用。目标是仅在工作线程执行大量计算时显示指标。另外,使用连接绑定,我无法使其工作。谁能帮助我解决这个问题,或提供其他解决方案。

谢谢

1 个答案:

答案 0 :(得分:0)

不使用线程时的问题是实际上阻止了UI,并且无法更新BusyIndi​​cator。 如果您正在使用线程,则会出现问题,在您触发线程后(而不是等待它完成),BusyIndi​​cator会立即设置为running=false

您应该设置一个属性,告知该工人是否在工作

(注意:未经测试!信号可能存在​​线程问题)

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();
    }

    ....
}

然后在QML中,您可以绑定到此属性:

BusyIndicator {
    id: indicator
    running: obj.working
}

或者,您可以查看WorkerScript(在Qml方面)或QRunnable(在C ++方面)