BusyIndi​​cator没有出现

ast*_*tre 5 qt qml qtquick2 qtquickcontrols

我想展示一个BusyIndicator漫长的过程正在进行中.问题是它在我运行时没有显示,并且在完成该过程后显示.根据文件

繁忙指示符应用于指示正​​在加载内容时的活动,或者阻止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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,当Rectangle单击时,我想显示BusyIndicator时间直到计算完成.

例如,我在这里使用了for循环.在实际场景中,我通过调用一个函数(在数据库中插入大约1000行)ContextProperty.但在那种情况下,BusyIndicator也没有显示.

我是以正确的方式做到的吗?或者最好的方法是什么?

fol*_*bis 6

您无法查看您的BusyIndicator仅仅因为onClicked处理程序块中的长操作应用程序GUI和指示器不会更新.您应该在不同的线程中运行此类操作以避免冻结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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

handle.js

WorkerScript.onMessage = function(message) {
    if(message.run === true) {
        for(var a=0;a<1000000;a++) { console.log(a) }
    }
    WorkerScript.sendMessage({run : false});
}
Run Code Online (Sandbox Code Playgroud)


Mit*_*tch 3

有一种方法可以使用QQuickWindow'safterSynchronizing信号来做到这一点:

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, ";
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这个想法是使用 aLoader来控制昂贵的操作何时发生。您还可以通过Qt.createQmlObject()Qt.createComponent()在单独的文件中动态加载组件来使用动态加载的组件。

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

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

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

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

一旦Loader完成加载文本,其item属性将变为非空并且BusyIndicator消失。