Qt: QWidget::paintEngine: ne Doit plus être appelé
Je suis en train de faire une application où vous pouvez dessiner avec votre doigt sur une toile.
Pour y parvenir, je suis sous-classement QWidget comme MFCanvas, enregistré le classe dans QML avec
qmlRegisterType<>(), la mise en œuvre de l'virtuel paintEvent(); la fonction, et
dessin avec un QPainter à l'intérieur de la paintEvent(); fonction.
Le Problème:
Lors de la construction, le QPainter lance cet avertissement:
QWidget::paintEngine: Should no longer be called
Ensuite, plusieurs autres mises en garde sont jetés:
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
Pas étonnant: le QPainter n'ai pas de dessiner n'importe quoi...
Aussi, suis-je censé appeler paintEvent(); par moi-même?
Ou doit-elle être appelée à chaque image par QWidget, et j'ai un peu foiré?
J'ai cherché sur le web, mais tous les posts que j'ai trouvé avait pas de réponse, ou où ils
en utilisant autre chose que de QWidget.
Mon 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();
}
}
principal.qml: (le plus important)
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
import com.cpp.mfcanvas 1.0
ApplicationWindow {
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);
}
}
//...
}
}
Dites-moi si vous avez besoin d'informations supplémentaires.
Je vous remercie à l'avance! =)
OriginalL'auteur PH-zero | 2014-09-11
Vous devez vous connecter pour publier un commentaire.
C'est bien expliqué ici:
https://forum.qt.io/topic/64693
En bref: ne pas essayer de peindre à partir de l'entrée gestionnaire d'événement directement,
mais la surcharge de la méthode paintEvent dans votre widget de la place et de créer la
QPainter. Utilisez l'entrée de l'événement exclusivement pour modifier l'interne
modèle de données et l'utilisation QPainter dans paintEvent à afficher, sur le chemin de la sortie.
OriginalL'auteur anonymous
Dans votre mfcanvas.cpp,
void MFCanvas::pressed(float x, float y)
fonction, la lignesemble être dérangeant. Essayé dans un code similaire - je reçois la même erreur.
Solution proposée: à l'aide de
this->repaint()
outhis->update()
au lieu depaintEvent(NULL)
pour repeindre un widget semble être plus approprié.Explication Possible: ressemble paintEvent() ne devraient pas être appelée de ce simple (comme paintEvent() est appelée lorsque paint() fonction est appelée). Aussi loin que je comprends de la QPainter doc, le QPainter travaille en collaboration avec le QPaintDevice et la QPaintEngine, ces trois éléments forment la base pour la peinture. L'erreur
QWidget::paintEngine: Should no longer be called
met bien droit. Les lignesprobablement indiquer qu'il n'y a pas de QPaintEngine fournis par ce peintre QPaintDevice (comme
QPaintDevice::paintEngine
). On peut supposer que cette QPaintEngine est généré ou autrement appelé à l'existence par la peinture de l'appareil lui-même, par exemple, lorsque le paint() fonction est appelée sur un widget.OriginalL'auteur viddik13
J'ai trouvé une solution simple moi-même:
Au lieu de dérivation de QWidget, dérivent de QQuickPaintedItem. QQuickPaintedItem est une classe qui a été fait exactement ce que j'ai besoin: de la Peinture sur un QML-Élément à l'aide d'un QPainter. Voici le Code (Réduit à l'essentiel):
mfcanvas.h:
mfcanvas.cpp:
Comme vous pouvez le voir, un simple paint() la fonction est fournie pour les mains sur un pointeur vers un QPainter, prêt à l'emploi. =)
OriginalL'auteur PH-zero