首页 > 解决方案 > QML 中的进度条实现以显示 C++ 中循环的进度

问题描述

我有我的 QML UI 和我的 C++ 代码。我需要展示其进度的循环是用 C++ 开发的,如下所示:

for(unsigned int j = 0; j < Count; ++j) {
    // Do stuff
}

在我的 QML 代码上,我需要这样的进度条:

ProgressBar {
    value: j  // Should come from C++ loop
              // It is "j" on C++ loop
    from: 0   // C++ loop starts out with 0
    to: Count // C++ loop ends with "Count"
}

我不知道我的 C++ 循环和我的 QML 进度条需要如何相互链接。我找不到任何相关的例子。任何人都可以给我一个提示。


我的 C++ 和 QML 之间的通信是通过这样使用来完成的Q_PROPERTY,但我不知道如何使用它:

Q_PROPERTY(float j READ j WRITE setJ NOTIFY jChanged)

标签: c++qtqml

解决方案


这简单!让我们一步一步来。

  1. 你的 C++ 类应该在里面扩展QObject和使用Q_OBJECT宏。例如,我称之为Worker

    class Worker : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(float progress READ progress NOTIFY progressChanged)
    public:
        Q_INVOKABLE void start() {
            // start the worker thread in which your loop spins
        }
        float progress(); // progress getter
    signals:
        void progressChanged(float progress);
    };
    
  2. 启动一个后台线程并定义它自己的progressChanged信号。

    for(unsigned int j = 0; j < Count; ++j) {
        // Do stuff
        emit progressChanged(/*current progress*/);
    }
    
  3. 将后台线程连接progressChanged到主线程活动对象WorkerprogressChanged信号(排队连接)。需要此步骤将信号从后台线程中继到 QML。

  4. 将 C++ 类链接到 QML:

    int main(int argc, char *argv[]) {
        QGuiApplication app(argc, argv);
    
        QQuickView view;
        Worker w;
        view.engine()->rootContext()->setContextProperty("worker", &w);
        view.setSource(QUrl::fromLocalFile("MyItem.qml"));
        view.show();
    
        return app.exec();
    }
    
  5. 在 QML 端收听信号:

    ProgressBar {
        id: prg
        from: 0   // C++ loop starts out with 0
        to: Count // C++ loop ends with "Count"
    
        Connections {
            target: worker
            onProgressChanged: prg.value = progress;
        }
    }
    

推荐阅读