首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BusyIndicator没有出现

BusyIndicator没有出现
EN

Stack Overflow用户
提问于 2014-12-01 05:32:44
回答 3查看 4.7K关注 0票数 5

我想在一个漫长的过程中展示一个BusyIndicator。问题是,当我让它运行时,它不会出现,当进程完成后,它就会显示出来。根据医生的说法

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

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

代码语言:javascript
复制
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也不会显示。

我这样做对吗?或者什么是最好的方法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-12-02 14:07:06

有一种方法可以使用QQuickWindowafterSynchronizing信号来实现:

代码语言:javascript
复制
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: 58:12:608呈现的窗口内容

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

当信号最初发出时,我们可以确保BusyIndicator已经启动了它的动画,因此用户实际上会看到一个旋转图标。

一旦Loader完成了文本加载,它的item属性将变为非空,BusyIndicator将消失。

票数 3
EN

Stack Overflow用户

发布于 2014-12-01 06:12:31

您不能仅仅因为BusyIndicator处理程序中的长时间操作阻止应用程序GUI和指示器不更新而查看onClicked。您应该在另一个线程中运行这样的操作,以避免冻结GUI。简单的例子:

QML

代码语言:javascript
复制
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

代码语言:javascript
复制
WorkerScript.onMessage = function(message) {
    if(message.run === true) {
        for(var a=0;a<1000000;a++) { console.log(a) }
    }
    WorkerScript.sendMessage({run : false});
}
票数 6
EN

Stack Overflow用户

发布于 2015-02-25 08:42:48

今天遇到同样的问题!我假设您是从一个名为BusyIndicator的C++属性控制您的busy。在计算之前将busy设置为true,在计算后设置为false。这样做解决了我的问题。这不是一个非常优雅的解决方案,但它有效:

QML

代码语言:javascript
复制
BusyIndicator {
    running: CPPModule.busy
}

CPP

代码语言:javascript
复制
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);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27222247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档