miriskrit
miriskrit

Reputation: 77

draw with the mouse on QQuickPaintedItem

I have this code

class cCanvas : public QQuickPaintedItem
..
..
void cCanvas::paint(QPainter *ppainter)
{
    ppainter->setPen(QPen(colorValue()));
    ppainter->drawLine(0, 0, rand() % 255 ,100);
}

QML

MultiPointTouchArea {
    onPressed {
        canvas.update();
    }
}

It works, but when drawing each new line, the canvas is cleared, previous line is deleted. But I want the lines to stay.

QML Canvas have requestPaint();

How to call this method for QQuickPaintedItem?

How to correctly create the ability to draw with the mouse on QQuickPaintedItem?

(Drawing on the QML canvas itself is not suitable because of the speed of work, since drawing occurs using calculations)

Upvotes: 2

Views: 901

Answers (1)

eyllanesc
eyllanesc

Reputation: 243907

Qt does not keep a cache of what was painted, so you only see what was painted last. A possible solution is to save the line instructions in a QPainterPath:

#ifndef CCANVAS_H
#define CCANVAS_H

#include <QPainterPath>
#include <QQuickPaintedItem>

class CCanvas : public QQuickPaintedItem
{
    Q_OBJECT
    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
    QML_ELEMENT
public:
    CCanvas(QQuickItem *parent = nullptr);
    Q_INVOKABLE void requestPaint();
    void paint(QPainter *painter);
    const QColor &color() const;
    void setColor(const QColor &newColor);

signals:
    void colorChanged();

private:
    QPainterPath m_path;
    QColor m_color;
};

#endif // CCANVAS_H
#include "ccanvas.h"

#include <QPainter>

CCanvas::CCanvas(QQuickItem *parent):QQuickPaintedItem(parent)
{

}

void CCanvas::requestPaint()
{
    QPointF start(0, 0);
    QPointF end(rand() % 255, 100);
    m_path.moveTo(start);
    m_path.lineTo(end);
    update();
}

void CCanvas::paint(QPainter *painter)
{
    painter->setPen(QPen(m_color));
    painter->drawPath(m_path);
}

const QColor &CCanvas::color() const
{
    return m_color;
}

void CCanvas::setColor(const QColor &newColor)
{
    if (m_color == newColor)
        return;
    m_color = newColor;
    emit colorChanged();
    update();
}
import QtQuick 2.12
import QtQuick.Window 2.12
import Canvas 1.0

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

    CCanvas{
        id: canvas
        anchors.fill: parent
        color: "red"
    }

    Timer {
        interval: 500; running: true; repeat: true
        onTriggered: canvas.requestPaint()
    }
}
QT += quick

CONFIG += c++11
SOURCES += \
        ccanvas.cpp \
        main.cpp

HEADERS += \
        ccanvas.h

RESOURCES += qml.qrc

CONFIG += qmltypes
QML_IMPORT_NAME = Canvas
QML_IMPORT_MAJOR_VERSION = 1

A similar solution can be done with a QImage.

Upvotes: 2

Related Questions