QML如何强制更新/重新绘制

时间:2019-11-26 12:22:48

标签: qt qml

在我的应用程序中,我有一个通过单击按钮开始的过程。该按钮已经具有一个属性,以指示它何时处于忙状态,这会更改颜色以反映忙状态。该过程完成后,busy属性将重新设置为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

更新功能不带参数。

1 个答案:

答案 0 :(得分:0)

调用该函数时,它仅阻塞了GUI线程,并且已放入事件队列的那些事件将等待,直到程序再次返回事件循环。这就是为什么您看不到按钮根据属性更改而更新的原因。 发生这种情况是因为设计不正确。根据Qt文档:

  
      
  • 尽可能使用异步的,事件驱动的编程
  •   
  • 使用辅助线程进行大量处理
  •   
  • 永远不要手动旋转事件循环
  •   
  • 在阻塞功能中每帧花费的时间绝不会超过几毫秒
  •   

您不应从GUI线程中调用阻止函数。您需要从另一个线程运行该函数,或者如果您打算这样做,则可以使用Timer调用该函数,这是很糟糕的事情。

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;
 }
}