我已经在QML中创建了Canvas
,它具有多个属性。 Canvas
将根据这些属性绘制一些内容,并且我想一次使用函数requestPaint
(如果某些属性更改),因此我不必多次重绘Canvas
。
是否可以将多个onPropertyChanged
事件合并为一个事件?
可以像if(onAChanged || onBChanged)
一样工作吗?
谢谢您的帮助!
答案 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: 1
或beforeRendering
-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