3

Qt Creator を使用して、メイン ウィンドウ内に 2 つのサブ ウィンドウがあり、いくつかのプッシュ ボタンを使用して画像を読み込み、保存し、ペンの幅と色をウィンドウにペイントするようにウィジェットを作成しました。しかし、ペイントを開始すると、次のエラーが表示されます

 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 ++も初めてなので、解決策を見つけるのを手伝ってください

これは以下の私のコードです

ウィジェット.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();
}

ウィジェット.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;
}

ウィジェット.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>
4

1 に答える 1

7

ウィジェットでのすべての描画はpaintEvent()関数内で行う必要があり、その外側で描画しようとしている - それは機能しません。

すべての描画呼び出しをpaintEvent()関数内に配置する方法を見つけるか、たとえば aQPixmapなどのバッファーに描画してから、そのピックスマップをウィジェットにpaintEvent()描画する必要があります。バッファーに描画すると、どこからでも描画できますが、制限は次のとおりです。ウィジェットの描画のみ。ピックスマップの場合、(通常) メインスレッドから描画する必要があります。別のスレッドから描画する場合は、QImage代わりに使用します。

于 2016-02-29T20:38:10.203 に答える