我希望在漫长的过程中显示BusyIndicator
。问题是它在我运行时没有显示,并且在完成该过程后显示。根据文件
忙碌指示符应用于指示正在加载内容时的活动,或阻止用户界面等待资源可用。
我创建了一个基于原始代码的最小代码
Window {
id: win
width: 300
height: 300
property bool run : false
Rectangle {
anchors.fill: parent
BusyIndicator {
anchors.centerIn: parent
running: run
}
MouseArea {
anchors.fill: parent
onClicked: {
run = true
for(var a=0;a<1000000;a++) { console.log(a) }
run = false
}
}
}
}
因此,当点击Rectangle
时,我想显示BusyIndicator
的时间,直到计算完成为止。
例如,我在这里使用了for循环。在实际场景中,我通过ContextProperty
调用一个函数(在数据库中插入大约1000行)。但在这种情况下,BusyIndicator
也不会显示。
我是以正确的方式做到的吗?或者最好的方法是什么?
答案 0 :(得分:5)
您无法仅仅因为BusyIndicator
处理程序中的长操作阻止应用程序GUI和指示器不更新而无法查看onClicked
。您应该在不同的线程中运行此类操作以避免冻结GUI。简单的例子:
<强> QML 强>
Window {
id: win
width: 300
height: 300
property bool run : false
Rectangle {
anchors.fill: parent
BusyIndicator {
id: busy
anchors.centerIn: parent
running: win.run
}
MouseArea {
anchors.fill: parent
onClicked: {
win.run = true
thread.sendMessage({run : true});
}
}
WorkerScript {
id: thread
source: "handler.js"
onMessage: {
win.run = messageObject.run;
}
}
}
}
<强> handle.js 强>
WorkerScript.onMessage = function(message) {
if(message.run === true) {
for(var a=0;a<1000000;a++) { console.log(a) }
}
WorkerScript.sendMessage({run : false});
}
答案 1 :(得分:3)
有一种方法可以使用QQuickWindow
的{{3}}信号来执行此操作:
import QtQuick 2.4
import QtQuick.Controls 1.3
ApplicationWindow {
width: 400
height: 400
visible: true
Component.onCompleted: print(Qt.formatDateTime(new Date(), "mm:ss:zzz"), "QML loaded")
onAfterSynchronizing: {
print(Qt.formatDateTime(new Date(), "mm:ss:zzz"), "Window content rendered")
if (!loader.item) {
loader.active = true
}
}
Item {
anchors.fill: parent
BusyIndicator {
running: !loader.item
anchors.centerIn: parent
}
Loader {
id: loader
active: false
anchors.fill: parent
sourceComponent: Text {
wrapMode: Text.Wrap
Component.onCompleted: {
for (var i = 0; i < 500; ++i) {
text += "Hello, ";
}
}
}
}
}
}
我们的想法是使用Loader
来控制昂贵的操作何时发生。您还可以通过Qt.createQmlObject()
或Qt.createComponent()
使用动态加载的组件,在单独的文件中动态加载组件。
如果您运行该示例,您将看到您获得以下输出:
qml:58:12:356 QML加载
qml:58:12:608呈现窗口内容
我们使用QQuickWindow
的{{3}}信号来了解窗口内容何时显示,并且仅在第一次(通过if (!loader.item)
)时对其进行操作。
当信号最初发出时,我们可以确定BusyIndicator
已经开始动画,所以用户实际上会看到一个旋转的图标。
Loader
加载完文字后,其item
属性将变为非空,BusyIndicator
将消失。
答案 2 :(得分:1)
今天遇到同样的问题!我假设您正在从名为BusyIndicator
的C ++属性中控制busy
。您在计算之前将busy
设置为true
,然后将false
设置为BusyIndicator {
running: CPPModule.busy
}
。这样做解决了我。这不是一个非常优雅的解决方案,但它有效:
<强> QML 强>
void CPPModule::setBusy(const bool &busy)
{
m_busy = busy;
emit busyChanged();
}
void CPPModule::InsertIntoDB()
{
setBusy(true);
QThread::msleep(50);
QCoreApplication::processEvents();
/*
very Long Operation
*/
setBusy(false);
}
<强> CPP 强>
{{1}}