I'm trying to make an app where you can draw with your finger on a canvas.
To achieve this, I'm subclassing QWidget
as MFCanvas
, registered the class in QML withqmlRegisterType<>()
, implementing the virtual paintEvent();
function, and
drawing on it with a QPainter
inside the paintEvent();
function.
The Problem:
Upon construction, the QPainter
throws this warning:
QWidget::paintEngine: Should no longer be called
Then, serveral other related warnings are thrown:
QPainter::begin: Paint device returned engine == 0, type: 1QPainter::setPen: Painter not active
No wonder: the QPainter
didn't draw anything...
Also, am i supposed to call paintEvent();
by myself?
Or should it be called every frame by QWidget
, and i somehow messed it up?
I searched the web, but all posts i found had either no answer to them, or they where
using something else than QWidget
.
My Code:
mfcanvas.cpp:
#include "mfcanvas.h"#include <QDebug>#include <QPainter>#include <QVector2D>#include <QList>MFCanvas::MFCanvas(QWidget *parent) : QWidget(parent){ paths = new QList<QList<QVector2D>*>(); current = NULL; QWidget::resize(100, 100);}MFCanvas::~MFCanvas(){ delete paths;}void MFCanvas::paintEvent(QPaintEvent *){ if(current!=NULL){ if(current->length() > 1){ QPainter painter(this); painter.setPen(Qt::black); for(int i = 1; i < current->length(); i++){ painter.drawLine(current->at(i-1).x(), current->at(i-1).y(), current->at(i).x(), current->at(i).y()); } } }}void MFCanvas::pressed(float x, float y){ if(current==NULL){ qDebug() << "null:"<<current; current = new QList<QVector2D>(); current->append(QVector2D(x, y)); }else{ qDebug() << "current:"<<current; } paintEvent(NULL);}void MFCanvas::update(float x, float y){ current->append(QVector2D(x, y));}void MFCanvas::resize(int w, int h){ QWidget::resize(w, h);}
main.cpp:
#include <QApplication>#include <QQmlApplicationEngine>#include <QtQml>#include <QSurfaceFormat>#include "creator.h"#include "mfcanvas.h"int main(int argc, char *argv[]){ QApplication app(argc, argv); qmlRegisterType<MFCanvas>("com.cpp.mfcanvas", 1, 0, "MFCanvas"); QQmlApplicationEngine engine; QQmlComponent *component = new QQmlComponent(&engine); QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit())); Creator creator(component); QObject::connect(component, SIGNAL(statusChanged(QQmlComponent::Status)), &creator, SLOT(create(QQmlComponent::Status))); component->loadUrl(QUrl("qrc:///main.qml")); int rv; rv = app.exec(); delete component; return rv;}
creator.cpp:
#include "creator.h"#include <QQuickWindow>#include <QDebug>Creator::Creator(QQmlComponent *component){ this->component = component;}void Creator::create(QQmlComponent::Status status){ if(status == QQmlComponent::Ready){ QObject *topLevel = component->create(); QQuickWindow::setDefaultAlphaBuffer(true); QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel); QSurfaceFormat surfaceFormat = window->requestedFormat(); window->setFormat(surfaceFormat); window->show(); }}
main.qml: (the important part)
import QtQuick 2.2import QtQuick.Controls 1.1import QtQuick.Controls.Styles 1.2import QtQuick.Layouts 1.1import QtQuick.Window 2.0import com.cpp.mfcanvas 1.0ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("MFCanvas") onSceneGraphInitialized: { drawMenu.visible = true; lineWidth.visible = true; colorMenu.visible = true; drawMenu.visible = false; lineWidth.visible = false; colorMenu.visible = false; } Rectangle { id: main anchors.fill: parent property real toolsH: 15 property real iconW: 25 property real menuH: 8 property real menuW: 16 property real dpi: (Screen.logicalPixelDensity == undefined ? 6 : Screen.logicalPixelDensity) * 1.5 property color choosenColor: Qt.hsla(hue.value, saturation.value, luminance.value, 1) Text { anchors.centerIn: parent font.pointSize: 60 text: "MFCanvas" } MFCanvas { id: canvas Component.onCompleted: { canvas.resize(main.width, main.height); } } //... }}
Tell me if you need any additional information.
Thank you in advance! =)