Qt 总线指示器未显示

Qt 总线指示器未显示,qt,qml,qtquick2,qtquickcontrols,Qt,Qml,Qtquick2,Qtquickcontrols,我想在长过程进行时显示一个总线指示器。问题是,当我让它运行时,它不会显示,并且在流程完成后显示。根据文件 在加载内容或阻止UI等待资源可用时,应使用忙指示器指示活动 我已经创建了一个基于原始代码的最小代码 Window { id: win width: 300 height: 300 property bool run : false Rectangle { anchors.fill: parent BusyIndica

我想在长过程进行时显示一个
总线指示器。问题是,当我让它运行时,它不会显示,并且在流程完成后显示。根据文件

在加载内容或阻止UI等待资源可用时,应使用忙指示器指示活动

我已经创建了一个基于原始代码的最小代码

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
            }
        }
    }
}
窗口{
id:赢
宽度:300
身高:300
属性布尔运行:false
长方形{
锚定。填充:父级
总线指示器{
anchors.centerIn:父对象
跑步:跑步
}
鼠耳{
锚定。填充:父级
再次点击:{
运行=真

对于(var a=0;a您无法查看您的
BusyIndicator
,因为
onClicked
处理程序中的长时间操作会阻止应用程序GUI,并且指示器不会更新。您应该在不同的线程中运行此类操作,以避免冻结GUI。简单示例:

QML

BusyIndicator {
    running: CPPModule.busy
}
窗口{
id:赢
宽度:300
身高:300
属性布尔运行:false
长方形{
锚定。填充:父级
总线指示器{
id:忙
anchors.centerIn:父对象
跑步:赢,跑
}
鼠耳{
锚定。填充:父级
再次点击:{
win.run=true
sendMessage({run:true});
}
}
WorkerScript{
id:线程
来源:“handler.js”
onMessage:{
win.run=messageObject.run;
}
}
}
}
handle.js

WorkerScript.onMessage=函数(消息){
如果(message.run==true){

对于(var a=0;a有一种方法可以使用
QQuickWindow
的信号来实现这一点:

导入QtQuick 2.4
导入QtQuick.Controls 1.3
应用程序窗口{
宽度:400
身高:400
可见:正确
Component.onCompleted:print(Qt.formatDateTime(新日期(),“mm:ss:zzz”),“QML已加载”)
OnAfterSynchronization:{
打印(Qt.formatDateTime(新日期(),“mm:ss:zzz”),“渲染的窗口内容”)
如果(!loader.item){
loader.active=true
}
}
项目{
锚定。填充:父级
总线指示器{
正在运行:!loader.item
anchors.centerIn:父对象
}
装载机{
id:装载机
活动:错误
锚定。填充:父级
sourceComponent:文本{
wrapMode:Text.Wrap
Component.onCompleted:{
对于(变量i=0;i<500;++i){
text+=“你好,”;
}
}
}
}
}
}
其思想是使用
加载器
来控制昂贵的操作何时发生。您还可以通过
Qt.createQmlObject()
Qt.createComponent()
使用动态加载的组件在单独的文件中动态加载组件

如果运行该示例,您将看到以下输出:

qml:58:12:356加载的qml
qml:58:12:608渲染的窗口内容

我们使用
QQuickWindow
的信号来知道何时显示了窗口的内容,并且仅在第一次对其进行操作(通过
if(!loader.item)

当信号最初发出时,我们可以确定
BusyIndicator
已开始其动画,因此用户将实际看到一个旋转图标


<> >一旦代码>加载程序< /代码>已加载文本,其<代码>项目属性将变成非空,并且 /Cult>将消失。

今天进入相同的问题!我假定您正在从C++属性中控制< <代码> BuyType > Cube属性>代码>繁忙/代码>。在计算之前将code>转换为

true
,在计算之后将code>转换为
false
。这样做对我来说解决了这个问题。这不是一个非常优雅的解决方案,但它很有效:

QML

BusyIndicator {
    running: CPPModule.busy
}
CPP

void CPPModule::setBusy(const bool&busy)
{
忙=忙;
emit busyChanged();
}
void CPPModule::InsertIntoDB()
{
setBusy(真);
QThread::msleep(50);
QCoreApplication::processEvents();
/*
超长运行
*/
挫折(假);
}

在实际场景中,我有一个C++函数,它调用了OnCutt。可以在WorkerScript使用吗?如果C++中的处理程序可以用QToX轻松地完成这个操作,那么AN在计算完成后发送一些通知。好,我想避免:是否有任何可能的方法可以从QML本身执行类似于processEvents的操作?或者是否可以在单独的线程上运行BusyIndicator本身?您可以使用。它在线程池中为长时间运行的进程生成一个线程,并返回一个。然后,您可以使用一个信号来查看任务何时完成,并在任务完成时获得任何结果xists。“已完成”信号在创建QFutureWatcher的同一线程中发出,因此您不必处理任何同步。@Jairo,除此之外的任何事情?请参阅我前面评论的其他部分。
Busyindicator
是否旋转?因为如果您使用的是非线程版本的QML渲染器(例如,在Windows上)我看不出
BusyIndicator
如何在没有进一步
processEvents()
调用“非常长的操作”部分的情况下旋转。对于长时间、耗时的任务,只需使用线程。就是这样。是的,它旋转了!我提供的代码对我来说工作得非常好,但我真的不知道为什么,尤其是msleep(50)是一个阻塞函数。它是阻塞的。在哪个平台上?如果后端是线程化的,那么当您阻塞该线程时,它是完全有意义的,不是吗