理解QML中的`markdirty()`

问题描述 投票:1回答:1

我不确定markdirty()函数在QML中的作用。该功能的QT文档对我来说似乎并不清楚。

enter image description here

我对此的解释是,它允许我们跟踪对画布的一小部分的更改,以便对该部分的任何更改仅使用paint()重绘该部分中的所有内容。

另一方面,做requestPaint()效率会低得多,因为它会重绘整个画布。

它是否正确?一些简单的示例代码对于理解markDirty()的用例非常有帮助

qt qml
1个回答
2
投票

这是编程尤其是GUI中广泛使用的术语。使用它可以将画布的一部分标记为需要更新。因此,如果此部分可见,渲染引擎将尽快触发paint(rect region)。在onPaint处理程序中,您应该只重绘此区域内的项目。 requestPaint()几乎完全相同,但对于所有可见区域。

检查以下示例中的输出:

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 800
    height: 800
    title: qsTr("QML Test")


    Canvas {
        property var shapes: [20,20,220,20,20,220,220,220]
        id: canvas
        width: 400
        height: 400
        anchors.centerIn: parent
        onPaint: {
            console.log(region);
            var ctx = getContext("2d");
            ctx.beginPath();
            ctx.fillStyle = Qt.rgba(Math.random(),Math.random(),Math.random(),1);
            // draw 4 circles
            for(var i = 0;i < canvas.shapes.length;i +=2) {
                var x = canvas.shapes[i];
                var y = canvas.shapes[i + 1];
                var width = 160;
                var height = 160;
                // check the circle is inside the region
                if(!( (x + width) < region.x  || x > (region.x + region.width) || (y + height) < region.y  || y > (region.y + region.height) ) ) {
                    ctx.ellipse(x, y, width, height);
                }
            }
            ctx.fill();
        }
    }

    Timer {
        id: timer
        property int step: 0
        interval: 2000
        repeat: true
        running: true
        onTriggered: {
            switch(step++) {
                case 0: canvas.markDirty(Qt.rect(0, 0, 200, 200)); break;
                case 1: canvas.requestPaint(); break;
                case 2: timer.stop(); break;
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.