我有一个 qml 应用程序,它根据用户请求执行相当长的操作。在此期间,我想在整个屏幕上显示覆盖层,以便用户知道应用程序正在运行,基本上是一个忙碌指示器。
我的问题是,应用程序在更新 UI 组件之前从任务启动。这是一个演示该问题的最小示例:
import QtQuick 2.9
import QtQuick.Window 2.3
Window {
visible: true
width: 640
height: 480
title: qsTr("Ui Demo")
Rectangle {
id: rectangle
anchors.fill: parent
color: "green"
}
MouseArea {
id: action
anchors.fill: parent
onClicked: {
rectangle.color = "red"
for(var i = 0; i < 10000; i++)
console.log(i)
}
}
}
我想要的是,当 for
循环运行时,矩形
的颜色变成红色,但我看到的行为是颜色仅在循环后改变已完成。
我也尝试了以下方法,没有任何区别:
Rectangle {
id: rectangle
anchors.fill: parent
color: "green"
onColorChanged: {
for(var i = 0; i < 10000; i++)
console.log(i)
}
}
我知道,最干净的解决方案是在不同的线程上执行繁重的工作,以免阻塞 UI 线程。但我不想这样做,因为在我的实际应用程序中,阻塞工作是更新 ListModel,这(例如,如 here 所示)
Qt views unfortunately don't know how to deal with [when they are] in foreign threads.
所以I would need to implement a new, asynchronous Model class ,这是我的客户目前不愿意付出的精力和时间。
因此我的问题是:如何确保在设置属性后立即重新绘制/更新 UI?
最佳答案
一种可能的方法是通过定时器
将“for”的顺序逻辑转换为异步逻辑:
import QtQuick 2.9
import QtQuick.Window 2.3
Window {
visible: true
width: 640
height: 480
title: qsTr("Ui Demo")
Rectangle {
id: rectangle
anchors.fill: parent
color: "green"
}
MouseArea {
id: action
anchors.fill: parent
onClicked: {
rectangle.color = "red"
timer.start()
}
}
Timer{
id: timer
interval: 1
property int counter: 0
repeat: true
onTriggered: {
counter += 1
console.log(counter)
if(counter > 100000)
timer.stop()
}
}
}
关于qt - 如何在 qml 中触发显式 UI 更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50944508/