在QML中将多个on <property> Changed事件合并为一个

时间:2018-08-09 08:28:13

标签: qml

我已经在QML中创建了Canvas,它具有多个属性。 Canvas将根据这些属性绘制一些内容,并且我想一次使用函数requestPaint(如果某些属性更改),因此我不必多次重绘Canvas

是否可以将多个onPropertyChanged事件合并为一个事件? 可以像if(onAChanged || onBChanged)一样工作吗?

谢谢您的帮助!

2 个答案:

答案 0 :(得分:1)

如果要在更改多个属性时执行操作,但又不想在一次调用多个属性时多次调用操作,则可以使用Qt.callLater(function)。 在下一个事件循环滴答时,它将仅调用一次该函数。

function someFunction() { /* ... */ }
onPropAChanged: Qt.callLater(someFunction)
onPropBChanged: Qt.callLater(someFunction)

但是,对于您而言,实际上是不需要的。 requestPaint不会引起Canvas的绘制,它只是通知场景图需要重新绘制。一次调用多次将只对画布进行一次重新绘制。您可以通过在画布的onDraw上的控制台上打印一些内容来进行验证。

答案 1 :(得分:0)

不,您不能将多个属性更改信号合并为一个。对于依赖信号的其他事物,这将是一个问题。

但是您可以将一个功能连接到多个信号。

function doSomething() { ... }
onAChanged: doSomething()
onBChanged: doSomething()

您可能还会发出一个信号:

signal someThingsChanged()
onAChanged: someThingsChanged()
onBChanged: someThingsChanged()
onSomeThingsChanged: { ... }

还可以使用[脚本]将功能自动连接到多个/所有信号:

Connect dynamically to signals of dynamically created objects


为避免多次调用广告位,您可以设置一个bool属性,例如:

property bool dirty

并检查它,例如每个渲染周期一次。

我认为带有interval: 1beforeRendering-signal的计时器应该可以完成这项工作。


但是,您尝试执行的操作很可能是不必要的,因为requestPaint不会直接触发paint,并且这些请求的 collection 已由Canvas。作为证明,请参见以下小示例:

Timer {
    interval: 100
    running: true
    repeat: true
    onTriggered: {
        console.log('RequestPaint')
        cvs.requestPaint()
    }
}
Timer {
    interval: 100
    running: true
    repeat: true
    onTriggered: {
        console.log('RequestPaint')
        cvs.requestPaint()
    }
}
Timer {
    interval: 100
    running: true
    repeat: true
    onTriggered: {
        console.log('RequestPaint')
        cvs.requestPaint()
    }
}

Canvas {
    id: cvs
    width: 100
    height: 100
    onPainted: console.log('Painted')
    onPaint: {
        var ctx = getContext("2d");
        ctx.fillStyle = Qt.rgba(1, 0, 0, 1);
        ctx.fillRect(0, 0, width, height);
    }
}

三个计时器都调用requestPaint,但是onPainted仅被调用一次。

qml: RequestPaint
qml: RequestPaint
qml: RequestPaint
qml: Painted
qml: RequestPaint
qml: RequestPaint
qml: RequestPaint
qml: Painted