0

I am trying to create very simple application in QT QML using QtQuick 2.7. I added on the canvas one rectangle, and after pushing the button I want to add another rectangle. Problem is, that the rectangle which should appear after button click is not created (I cannot see it on canvas), but console.log() output Button 1 cliceked I see. What I am doing wrong? Is there any need to refresh the canvas or something? My code is:

Page1Form {
    property alias canvas: canvas
    button1.onClicked: {
        console.log("Button 1 clicked.");
        var ct = canvas.getContext("2d");
        ct.fillStyle = Qt.rgba(0, 0, 1, 1);
        ct.fillRect(50, 50, 10, 10);//this doesnt work
    }
    Canvas {
        id: canvas
        x: 16
        y: 39
        width: 342
        height: 517
        onPaint: {
                var ctx = getContext("2d");
                ctx.fillStyle = Qt.rgba(1, 1, 1, 1);
                ctx.fillRect(10, 10, 10, 10);
        }
    }
}

1 Answer 1

4

Canvas only repaints after being asked to. See the documentation for the paint() signal:

This signal is emitted when the region needs to be rendered. If a context is active it can be referenced from the context property.

This signal can be triggered by markdirty(), requestPaint() or by changing the current canvas window.

So, after doing your drawing, call requestPaint():

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Column {
        anchors.fill: parent
        Canvas {
            id: canvas
            width: parent.width
            height: 300
            onPaint: {
                var ctx = getContext("2d");
                ctx.fillStyle = Qt.rgba(1, 0, 1, 1);
                ctx.fillRect(10, 10, 10, 10);
            }
        }
        Button {
            text: "Add"
            onClicked: {
                console.log("Button 1 clicked.");
                var ct = canvas.getContext("2d");
                ct.fillStyle = Qt.rgba(0, 0, 1, 1);
                ct.fillRect(50, 50, 10, 10);//this doesnt work
                canvas.requestPaint();
            }
        }
    }
}

Although, this seems to me like an odd way of doing it; usually you respond to the canvas telling you that it's ready to paint via the paint() signal, not the other way around. What this means in practice is that your blue rectangles will be painted before (and hence underneath) the one in the onPaint handler.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.