qml 中是不是可以重绘 Canvas 对象的内容?

Posted

技术标签:

【中文标题】qml 中是不是可以重绘 Canvas 对象的内容?【英文标题】:Is it possible in qml to redraw content of the Canvas object?qml 中是否可以重绘 Canvas 对象的内容? 【发布时间】:2018-07-13 20:15:38 【问题描述】:

我有一个 Canvas 对象,它的 onPaint 方法如下所示:

onPaint: 
    var ctx = getContext("2d");
    ctx.fillStyle = Qt.rgba(1, 1, 1, 1);
    ctx.fillRect(0, 0, width, height);

只需用白色填充画布即可。

之后,当我按下某个按钮时,我想在这个 Canvas 上画一个点,我可以在 Button 对象的 onClick 方法中更改 Canvas 吗?对我来说,如果我想在 Canvas 上绘制一些东西,我需要调用 requestPaint(),但 requestPaint() 只会将所有 Canvas 填充为白色。所以,我看到了一种解决方案,我需要声明 property var point: [x, y] 并将 onPaint 方法更改为如下内容:

onPaint: 
    var ctx = getContext("2d");
    ctx.fillStyle = Qt.rgba(1, 1, 1, 1);
    ctx.fillRect(0, 0, width, height);
    //pseudocode
    if point is not empty:
        ctx.fillStyle = Qt.rgba(1, 0, 0, 1);
        ctx.fillRect(point.x, point.y, 1, 1)

它会起作用吗?有没有更好的方法来做我描述的事情? 谢谢。

【问题讨论】:

【参考方案1】:

一般而言,您可以创建一个空属性,并使用发生更改时发出的信号来调用requestPaint(),并在onPaint() 中绘制一个模拟该点的圆。

import QtQuick 2.0
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.2

ApplicationWindow 
    visible: true
    width: 640
    height: 480

    property var drawPoint: null
    onDrawPointChanged: canv.requestPaint()

    ColumnLayout 
        anchors.fill: parent
        anchors.margins: 9

        Button 
            height: 40
            Layout.fillWidth: true
            text: qsTr("Random Point")
            onClicked: drawPoint = Qt.point(Math.random()*canv.width ,Math.random()*canv.height);
        

        Canvas 
            id: canv
            Layout.fillWidth: true
            Layout.fillHeight: true
            onPaint: 
                var ctx = getContext("2d");
                ctx.fillStyle = Qt.rgba(1, 1, 1, 1);
                ctx.fillRect(0, 0, width, height);

                if(drawPoint !== null)
                    ctx.beginPath();
                    ctx.arc(drawPoint.x, drawPoint.y, 5, 0, 2 * Math.PI);
                    ctx.fillStyle = Qt.rgba(1, 0, 0, 1);
                    ctx.fill()
                    ctx.strokeStyle = Qt.rgba(1, 0, 0, 1);
                    ctx.stroke();
                
            
        
    

【讨论】:

以上是关于qml 中是不是可以重绘 Canvas 对象的内容?的主要内容,如果未能解决你的问题,请参考以下文章

在 QQuickWidget 中更新/重绘仪表

QML Canvas:渲染中的不同行为

理解QML中的`markdirty()`

如何在我的 C++ 代码中创建 QML 画布并在其上附加视频?比如Java Canvas我可以

vue中判断canvas画布是不是为空

js中的canvas画图,clearrect清除画布之后,重绘页面空白,重绘不出来,但没报错,js方法正常执行。