简体   繁体   English

无法在Qt Widget上绘制,显示错误“paintEngine:不应再被调用”

[英]Unable to paint on Qt Widget, shows error “paintEngine: Should no longer be called”

I have created a widget using Qt Creator such a way that it has two sub windows inside a main window and some push buttons to load, save images, set pen width and color to paint on the window. 我使用Qt Creator创建了一个小部件,它在主窗口内有两个子窗口,一些按钮可以加载,保存图像,设置笔宽和颜色以在窗口上绘画。 But when i start to paint it gives me error saying 但是,当我开始绘画时,它给我错误的说法

 QWidget::paintEngine: Should no longer be called  
 QPainter::begin: Paint device returned engine == 0, type: 1  
 QPainter::setPen: Painter not active  
 QPainter::drawPoints: Painter not active

Does anyone know what mistake i am doing, i checked threads related to this topic but could not find suitable solution. 有谁知道我在做什么错,我检查了与此主题相关的线程但找不到合适的解决方案。 I am also new to c++, so please help me to find a solution 我也是c ++的新手,所以请帮我找一个解决方案

This is my code below 这是我的代码

widget.h widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtCore>
#include <QImage>
#include <QColor>
#include <QPoint>
#include <QtGui>
#include <QPainter>
#include <QMainWindow>
#include <QFileDialog>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

    bool isModified() const { return modified; }
    QColor penColor() const { return newPenColor; }
    int penWidth() const { return newPenWidth; }


protected:
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;

private slots:
    void on_open_clicked();

    void on_save_clicked();

    void on_penWidth_clicked();

    void on_penColor_clicked();

private:
    Ui::Widget *ui;

    QImage image;
    QPixmap imageobject;
    int newPenWidth;
    QColor newPenColor;
    bool modified;
    bool scribbling;
    QPoint firstPoint, secondPoint;
    void drawFirstPoint(const QPoint);
    void drawSecondPoint(const QPoint);
};

#endif // WIDGET_H

main.cpp main.cpp中

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

widget.cpp widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QtWidgets>
#ifndef QT_NO_PRINTER
#include <QtPrintSupport/QPrinter>
#include <QtPrintSupport/QPrintDialog>
#endif
#include <QLabel>
#include <QWidget>


Widget::Widget(QWidget *parent) : QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    setAttribute(Qt::WA_StaticContents);
    modified = false;
    scribbling = false;
    newPenWidth = 1;
    newPenColor = Qt::blue;
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_open_clicked()
{
    QString filename = QFileDialog::getOpenFileName(this, tr("choose"), "", tr("Image(*.png *.jpg *.jpeg *.bmp *.gif)"));
       if (QString::compare(filename, QString())!=0)
       {
           QImage image;
           bool valid = image.load(filename);
           if (valid)
           {
               image = image.scaledToWidth(ui->inputWindow->width(), Qt::SmoothTransformation);
               ui->inputWindow->setPixmap(QPixmap::fromImage(image));

               image = image.scaledToWidth(ui->outputWindow->width(), Qt::SmoothTransformation);
               ui->outputWindow->setPixmap(QPixmap::fromImage(image));
           }
           else
           {
               //Error handling
           }
       }
}

void Widget::on_save_clicked()
{
    QString filename = QFileDialog::getSaveFileName(this,tr("choose"), "", tr("PNG (*.png);; JPEG (*.jpg *.jpeg);; BMP(*.bmp);; GIF(*.gif)"));

    QImage imageobject = image;
    imageobject.save(filename);

}

void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QRect dirtyRect = event->rect();
    painter.drawImage(dirtyRect, image, dirtyRect);
}

void Widget::mousePressEvent(QMouseEvent *event)
{
    scribbling = true;
    if (event->button() == Qt::LeftButton && scribbling)
    {
        firstPoint = event->pos();
        drawFirstPoint(firstPoint);
    }
    else if (event->button() == Qt::RightButton && scribbling) {
             secondPoint = event->pos();
             drawSecondPoint(secondPoint);

    }
}

void Widget::drawFirstPoint(const QPoint)
{
    QPainter painter(this);
    painter.setPen(QPen(newPenColor, newPenWidth, Qt::SolidLine, Qt::RoundCap,
                        Qt::RoundJoin));

    painter.drawPoint(firstPoint);
    modified = true;
    int rad = (newPenWidth / 2) + 2;
    update(QRect(firstPoint, firstPoint).normalized().adjusted(-rad, -rad, +rad, +rad));
}

void Widget::drawSecondPoint(const QPoint)
{
    QPainter painter(this);
    painter.setPen(QPen(newPenColor, newPenWidth, Qt::SolidLine, Qt::RoundCap,
                        Qt::RoundJoin));

    painter.drawPoint(secondPoint);
    modified = true;
    int rad = (newPenWidth / 2) + 2;
    update(QRect(secondPoint, secondPoint).normalized().adjusted(-rad, -rad, +rad, +rad));
}

void Widget::on_penWidth_clicked()
{
    bool ok;
    int newWidth = QInputDialog::getInt(this, tr("Scribble"),
                                        tr("Select pen width:"),
                                        this->penWidth(), 1, 50, 1, &ok);
    if (ok)
        newPenWidth = newWidth;
}

void Widget::on_penColor_clicked()
{
    QColor newColor = QColorDialog::getColor(this->penColor());
    if (newColor.isValid())
        newPenColor = newColor;
}

widget.ui widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="enabled">
   <bool>true</bool>
  </property>
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1300</width>
    <height>700</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Test window</string>
  </property>
  <property name="layoutDirection">
   <enum>Qt::LeftToRight</enum>
  </property>
  <widget class="QLabel" name="inputWindow">
   <property name="geometry">
    <rect>
     <x>40</x>
     <y>120</y>
     <width>600</width>
     <height>500</height>
    </rect>
   </property>
   <property name="maximumSize">
    <size>
     <width>600</width>
     <height>16777215</height>
    </size>
   </property>
   <property name="cursor">
    <cursorShape>CrossCursor</cursorShape>
   </property>
   <property name="text">
    <string>TextLabel</string>
   </property>
  </widget>
  <widget class="QLabel" name="outputWindow">
   <property name="geometry">
    <rect>
     <x>660</x>
     <y>120</y>
     <width>600</width>
     <height>500</height>
    </rect>
   </property>
   <property name="maximumSize">
    <size>
     <width>600</width>
     <height>16777215</height>
    </size>
   </property>
   <property name="text">
    <string>TextLabel</string>
   </property>
  </widget>
  <widget class="QWidget" name="layoutWidget">
   <property name="geometry">
    <rect>
     <x>170</x>
     <y>10</y>
     <width>651</width>
     <height>31</height>
    </rect>
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout">
    <item>
     <widget class="QPushButton" name="open">
      <property name="cursor">
       <cursorShape>PointingHandCursor</cursorShape>
      </property>
      <property name="text">
       <string>OPEN</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="save">
      <property name="cursor">
       <cursorShape>PointingHandCursor</cursorShape>
      </property>
      <property name="text">
       <string>SAVE</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="penWidth">
      <property name="text">
       <string>Pen Width</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="penColor">
      <property name="text">
       <string>Pen Color</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="pushButton_5">
      <property name="text">
       <string>PushButton</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

All painting on a widget must happen in the paintEvent() function, and you are trying to paint outside of it - that won't work. 窗口小部件上的所有绘制必须在paintEvent()函数中进行,并且您尝试在其外部绘制 - 这将无法工作。

You must either find a way to put all your drawing calls inside the paintEvent() function, or draw on a buffer, for example a QPixmap and then draw that pixmap onto the widget in the paintEvent() When you draw on a buffer you can draw from everywhere, the limitation is only for widget drawing. 您必须找到一种方法将所有绘图调用放在paintEvent()函数中,或绘制缓冲区,例如QPixmap ,然后将该pixmap绘制到paintEvent()的小部件paintEvent()您在缓冲区上绘制时,您可以从任何地方抽取,限制仅适用于小部件绘图。 For pixmaps you (usually) must draw from the main thread, if you want to draw from another thread, use QImage instead. 对于pixmaps,你(通常)必须从主线程绘制,如果你想从另一个线程绘制,请使用QImage

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM