写一个动态创建qml控件的同时新开线程执行耗时操作且不导致界面卡断的示例程序
时间: 2023-06-12 10:04:53 浏览: 87
QML中动态创建组件(同步/异步)的方法
好的,下面是一个示例程序,实现了动态创建QML控件,并在新线程中进行耗时操作,不会导致界面卡断:
```
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Window 2.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Dynamic QML Control Creation")
// 定义一个组件,用于显示耗时操作的进度
Component {
id: progressComponent
Rectangle {
width: 200
height: 50
color: "gray"
Text {
anchors.centerIn: parent
text: "Progress: " + progress + "%"
}
}
}
// 定义一个函数,用于创建耗时操作的进度显示组件
function createProgressComponent() {
var component = Qt.createComponent(progressComponent);
var obj = component.createObject(parent);
return obj;
}
// 定义一个函数,用于在新线程中执行耗时操作
function doHeavyWork(progress) {
for (var i = 0; i < 100000000; i++) {
// 模拟耗时操作
if (i % 10000000 == 0) {
progress.progress = i / 1000000;
}
}
}
// 定义一个函数,用于创建QML控件并执行耗时操作
function createAndDoWork() {
// 创建一个进度显示组件
var progress = createProgressComponent();
// 在新线程中执行耗时操作
var workerThread = Qt.createQmlObject('import QtQuick 2.0; import QtQuick.Controls 2.0; WorkerScript { id: worker; function run() { doHeavyWork(progress) } }', parent);
workerThread.run();
// 创建一个文本框,显示耗时操作完成后的结果
var result = "";
var text = Qt.createQmlObject('import QtQuick 2.0; import QtQuick.Controls 2.0; Text { anchors.centerIn: parent; text: result }', parent);
// 等待耗时操作完成
workerThread.onMessage = function(msg) {
if (msg === "finished") {
result = "Heavy work done!";
text.text = result;
}
}
}
// 创建一个按钮,点击时调用createAndDoWork函数
Button {
text: "Create and Do Work"
anchors.centerIn: parent
onClicked: createAndDoWork()
}
}
```
在这个示例程序中,我们首先定义了一个用于显示耗时操作进度的组件,然后定义了一个函数createProgressComponent,用于创建这个组件。接着,我们定义了一个函数doHeavyWork,用于在新线程中执行耗时操作,并在执行过程中不断更新进度显示组件。最后,我们定义了一个函数createAndDoWork,用于创建QML控件并在新线程中执行doHeavyWork函数。在createAndDoWork函数中,我们首先调用createProgressComponent函数创建进度显示组件,然后在新线程中执行doHeavyWork函数,同时创建一个文本框用于显示耗时操作完成后的结果。最后,我们在按钮的点击事件中调用createAndDoWork函数即可。
需要注意的是,我们在新线程中执行耗时操作时使用了WorkerScript组件,这个组件可以让我们在新线程中执行代码,并且不会阻塞主线程。另外,在新线程中更新界面时,我们需要使用Qt.createQmlObject函数创建QML控件,而不是直接在新线程中操作已有的控件。这是因为QML控件只能在主线程中进行操作,如果在新线程中直接操作控件会导致程序崩溃。
阅读全文