如何在QML功能也异步的同时使用来自QML的QThread

时间:2019-05-14 09:07:34

标签: c++ multithreading qt qml qthread

我正在寻找在QML中使用QThread的方法。 我想将参数传递给QThread函数并从中返回布尔值。

从QML方面我想做的另一件事是,在应用程序执行脚本时不要阻塞该应用程序,该脚本将在调用/执行QThread之前发生。

下面是示例代码:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "testasync.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    qmlRegisterType<testAsync>("testAsync",1,0,"thread");//not working on main.qml
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
//import testAsync 1.0

ApplicationWindow {
    id: window
    title: "Stack"
    visible: true
    width: 1400

    Page {
        id: page
        anchors.fill: parent
        property int responsiveWidth: 1000
        property int maximumWidth: 900
        ScrollView {
            id:configScroll
            anchors.fill: parent
            GridLayout {
                columns: 2
                width: page.width > page.responsiveWidth ? page.maximumWidth : page.width
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.leftMargin: page.width > page.responsiveWidth ? (page.width - childrenRect.width)/2 : 10
                anchors.rightMargin: page.width > page.responsiveWidth ? 0 : 10
                //this function needs to be processed and will return the values we need for the testasync. this can't block UI thread too
                function teste() {
                            for(var i=0; i<10000000; i++)
                            {
                                console.log(i)
                            }
                  return "teste"
                 }
                    Button {
                        property bool test: true
                        text: "async"
                        onClicked: {
                            var val = parent.teste()
//                            if(test)
//                                val=thread.start()
//                            else
//                                val=thread.quit()
                            console.log(val)
                            test=!test
                        }
                    }
            }
        }
    }
}

testasync.h

#ifndef TESTASYNC_H
#define TESTASYNC_H
#include <QThread>
#include <QObject>

class testAsync : public QThread
{
    Q_OBJECT
public:
    testAsync();
    void run();
private:
    QString name;
};
#endif // TESTASYNC_H

testasync.cpp

#include "testAsync.h"
#include <QDebug>
#include <QtCore>
testAsync::testAsync(){}

void testAsync::run() {
    for(int i = 0; i <= 100; i++)
    {
        qDebug() << this->name << " " << i;
    }
    //return true
}

这些怎么办?

2 个答案:

答案 0 :(得分:2)

正确注册类型:

qmlRegisterType<testAsync>("TestAsync", 1, 0, "TestAsync");

在qml文件中创建您类型的实例,然后调用它的方法。

import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import TestAsync 1.0

ApplicationWindow {
    id: window
    title: "Stack"
    visible: true
    width: 1400

    TestAsync {
        id: threadAsync
    }

    Page {
        ....
                    Button {
                        property bool test : true
                        text: "async"
                        onClicked: {
                            if(test) {
                                val=threadAsync.start()
                            } else {
                                val=threadAsync.quit()
                            }
                            console.log(val)
                            test=!test
                        }
                    }
 ....
}

答案 1 :(得分:1)

您犯了一些错误,使您脱离了期望。

@folibis和@Hubi已经提到过-您使用了以小写字母开头的C ++类名。 QML有问题。


关于多线程,有很多方法可以做到。这真的取决于您的特定任务。

我确实建议您阅读下一篇文章(来自Qt官方文档):

由于您在Qt和QML中有信号,因此可以在C ++中实现所需的所有内容,然后将其放到QML中。

您可以参考我为您准备的simple project on GitHub。已实施moveToThread方法。