在我的应用程序中,我有一个通过单击按钮启动的进程。按钮已经有了一个属性来指示它什么时候忙,这会改变颜色以反映忙碌状态。当进程完成后,忙碌属性将被设置为false。
问题是,尽管这些步骤是:
button.busy = true
... Do something ...
button.busy = false
实际上,直到进程几乎完成后,按钮才会改变以反映繁忙状态,然后又会更改为非繁忙状态。
无论如何,我是否可以在将繁忙状态设置为true之后,以及在做一些使GUI更新和反映状态的操作之前,插入一些内容?
我的按钮QML:
Button {
id: root
property bool busy: false
property bool showDropShadow: true
property color bottomColour: MerlinStyle.greenButtonBottom
property color iconColour: "white"
property color topColour: MerlinStyle.greenButtonTop
property string icon: ""
opacity: (pressed || !enabled) ? 0.5 : 1.0
onBusyChanged: {
//Set the colours according to busy state
if ( root.busy == true ) {
root.bottomColour = MerlinStyle.indicatorOrange;
root.topColour = MerlinStyle.indicatorOrange;
} else {
root.bottomColour = MerlinStyle.greenButtonBottom;
root.topColour = MerlinStyle.greenButtonTop;
}
}
background: Item {
RadiusRectangle {
id: rect
anchors.fill: parent
radius: MerlinStyle.rectRadius
topLeftPointed: true
gradient: Gradient {
GradientStop { position: 0.0; color: root.topColour }
GradientStop { position: 1.0; color: root.bottomColour }
}
}
DropShadow {
visible: showDropShadow && !pressed && enabled
anchors.fill: rect
horizontalOffset: 1
verticalOffset: 2
color: "#80000000"
source: rect
}
}
contentItem: Item {
ColoredImage {
anchors.centerIn: parent
height: parent.height * 0.85
width: parent.width * 0.85
source: icon
color: root.iconColour
}
}
}
我尝试使用以下方法触发更新:
idOfButton.update
这总是导致:
Button_QMLTYPE_28 : Update called for a item without content
update函数不接受参数。
发布于 2019-11-26 13:48:47
当您调用该函数时,它只会阻塞GUI线程,而那些已经放到事件队列中的事件将等待直到程序再次返回到事件循环。这就是为什么您看不到根据属性更改更新按钮的原因。这是因为糟糕的设计。根据Qt文档:
在可能的情况下,processing
,手动旋转事件循环
中,每帧不超过几毫秒。
您不应该从GUI线程中调用阻塞函数。您需要从另一个线程运行该函数,或者如果您有此目的,您可以使用计时器调用您的函数,这是一个肮脏的黑客。
Timer{
id: dummyTimer
interval:1
repeat: false
running: false
onTriggered: {
control.someLazyBlockingFunction();
idOfButton.busy = false;
}
}
Button{
id: anotherButton
...
onClicked:{
idOfButton.busy = true;
dummyTimer.running= true;
}
}
发布于 2021-11-26 13:30:19
迟答,但可能会帮上忙。
在我的例子中,我的应用程序运行在python (PyQt5 + QML)上,事件来自QML代码,并且是在一个槽中处理的(这里没有什么新的)。问题是,正如qt文档中所述,您不能阻止主线程,因此,我找到的处理它的最佳方法是旋转一个新的守护进程线程,以运行事件代码而不挂起前端。
@pyqtslot(name="doMyButtonCallback")
def do_mybuttoncallback():
def mybuttonwork():
time.sleep(3)
print("i did not hang your code!"
t=threading.Thread(target=mybuttonwork)
t.daemon=True
t.start()
https://stackoverflow.com/questions/59050917
复制相似问题