如何在 QML 函数异步的同时使用 QML 中的 QThread
How to use QThread from QML while having QML function async too
我正在寻找在 QML 中使用 QThread
的方法。
我想将参数传递给 QThread
函数并从中 return 一个 bool 值。
我想从 QML 方面做的另一件事是,当应用程序执行将在 calling/executing 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
}
如何做到这些?
正确注册类型:
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
}
}
....
}
您犯了几个错误,导致您偏离预期。
正如@folibis 和@Hubi 已经提到的那样——您使用了以小写字母开头的 C++ class 名称。 QML 有问题。
关于multi-threading,有很多方法可以做到。这实际上取决于您的特定任务。
我真的建议你阅读下一篇文章(来自官方 Qt 文档):
由于您在 Qt 和 QML 中有信号,您可以在 C++ 中实现您想要的所有内容,然后将其放到 QML 中。
你可以参考这个simple project on GitHub我已经为你准备好了。实施了 moveToThread
方法。
我正在寻找在 QML 中使用 QThread
的方法。
我想将参数传递给 QThread
函数并从中 return 一个 bool 值。
我想从 QML 方面做的另一件事是,当应用程序执行将在 calling/executing 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
}
如何做到这些?
正确注册类型:
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
}
}
....
}
您犯了几个错误,导致您偏离预期。
正如@folibis 和@Hubi 已经提到的那样——您使用了以小写字母开头的 C++ class 名称。 QML 有问题。
关于multi-threading,有很多方法可以做到。这实际上取决于您的特定任务。
我真的建议你阅读下一篇文章(来自官方 Qt 文档):
由于您在 Qt 和 QML 中有信号,您可以在 C++ 中实现您想要的所有内容,然后将其放到 QML 中。
你可以参考这个simple project on GitHub我已经为你准备好了。实施了 moveToThread
方法。