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)是一个阻塞函数。它是阻塞的。在哪个平台上?如果后端是线程化的,那么当您阻塞该线程时,它是完全有意义的,不是吗