无法在Qt小部件上绘制,显示错误"paintEngine:不应再被调用". [英] Unable to paint on Qt Widget, shows error "paintEngine: Should no longer be called"

查看:51
本文介绍了无法在Qt小部件上绘制,显示错误"paintEngine:不应再被调用".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Qt Creator创建了一个小部件,这样它在主窗口内有两个子窗口,并带有一些按钮以加载,保存图像,设置笔宽度和颜色以在窗口上绘画.但是当我开始绘画时,它会给我错误提示

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. 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

有人知道我在做什么错误,我检查了与此主题相关的线程,但找不到合适的解决方案.我也是c ++的新手,所以请帮助我找到解决方法

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

这是我的下面的代码

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

#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>

推荐答案

在小部件上进行的所有绘画都必须在 paintEvent()函数中进行,而您尝试在其外部进行绘画-这样可以不行.

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()函数中,或者在缓冲区(例如 QPixmap )上进行绘制,然后进行绘制将像素图映射到 paintEvent()中的小部件上当在缓冲区上绘制时,您可以从任何地方进行绘制,该限制仅适用于小部件绘制.对于像素图,您(通常)通常必须从主线程中进行绘制,如果要从其他线程中进行绘制,请改用 QImage .

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. For pixmaps you (usually) must draw from the main thread, if you want to draw from another thread, use QImage instead.

这篇关于无法在Qt小部件上绘制,显示错误"paintEngine:不应再被调用".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆