簡體   English   中英

無法在Qt Widget上繪制,顯示錯誤“paintEngine:不應再被調用”

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

我使用Qt Creator創建了一個小部件,它在主窗口內有兩個子窗口,一些按鈕可以加載,保存圖像,設置筆寬和顏色以在窗口上繪畫。 但是,當我開始繪畫時,它給我錯誤的說法

 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 ++的新手,所以請幫我找一個解決方案

這是我的代碼

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

#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

<?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()函數中進行,並且您嘗試在其外部繪制 - 這將無法工作。

您必須找到一種方法將所有繪圖調用放在paintEvent()函數中,或繪制緩沖區,例如QPixmap ,然后將該pixmap繪制到paintEvent()的小部件paintEvent()您在緩沖區上繪制時,您可以從任何地方抽取,限制僅適用於小部件繪圖。 對於pixmaps,你(通常)必須從主線程繪制,如果你想從另一個線程繪制,請使用QImage

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM