目录
1. Qt绘图报错描述
当用QPainter绘图时,如果使用不当,Qt会报如下错误提示:

2. 错误原因及解决方法
2.1.第1种情况
绘图代码不在QWidget::paintEvent重载函数内或不在被QWidget::paintEvent函数调用的函数内。Qt规定:任何窗体内的绘图必须放在QWidget::paintEvent重载函数内或被QWidget::paintEvent函数调用的函数内。如下代码:
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
m_pImage = new QImage("b.png");
auto b = m_pImage->isNull();
Q_ASSERT(!b);
QPainter p(this);
p.drawImage(rect(), *m_pImage, m_pImage->rect());
}
原意是想把成员变量m_pImage表示的图像在Widget类的构造函数中绘制到Widget窗体类的矩形内,但报1节描述的错误。正确的做法是应把绘图代码移动到paintEvent重载函数内,即如下那样:
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
m_pImage = new QImage("b.png");
auto b = m_pImage->isNull();
Q_ASSERT(!b);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter p(this);
p.drawImage(rect(), *m_pImage, m_pImage->rect());
}
Widget.h文件如下:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
virtual void paintEvent(QPaintEvent *event) override;
private:
Ui::Widget *ui;
QImage* m_pImage;
};
#endif // WIDGET_H
2.2. 第2种情况
图像绘制到窗体中的小部件上,如:绘制图像到Widget窗体中的某个QLabel上,像如下代码那样:
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
m_pImage = new QImage("b.png");
auto b = m_pImage->isNull();
Q_ASSERT(!b);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter p(ui->label);
p.drawImage(ui->label->rect(), *m_pImage, m_pImage->rect());
}
其中ui->label为Widget窗体上的一个QLabel,同样报1节的错误。Qt规定:任何窗体子部件的绘图必须放在该子部件的paintEvent重载函数内或在被子部件的paintEvent函数调用的函数内。解决方法如下:
1):自定义子部件类。
2):在自定义部件类的paintEvent重载函数内绘图。
如下代码就是自定义了一个名为CMyLabel的类,在该类的paintEvent重载函数内绘图成功:
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
class CMyLabel : public QLabel
{
Q_OBJECT
public:
explicit CMyLabel(QWidget *parent = nullptr);
~CMyLabel();
private:
virtual void paintEvent(QPaintEvent *event) override;
private:
QImage* m_pImage;
};
#endif // MYLABEL_H
#include "myLabel.h"
#include "ui_myLabel.h"
#include<QPainter>
#include<QPaintEvent>
CMyLabel::CMyLabel(QWidget *parent) :
QLabel(parent)
{
m_pImage = new QImage("d:/b.png");
auto b = m_pImage->isNull();
Q_ASSERT(!b);
}
CMyLabel::~CMyLabel()
{
}
void CMyLabel::paintEvent(QPaintEvent *event)
{
QPainter p(this);
p.drawImage(rect(), *m_pImage, m_pImage->rect());
}

3. 总结
为了保证Qt绘图时不报错,能成功,必须遵循如下规定:
1):任何窗体内的绘图必须放在QWidget::paintEvent重载函数内或被QWidget::paintEvent函数调用
的函数内。
2):任何窗体子部件的绘图必须放在该子部件的paintEvent重载函数内或在被子部件的paintEvent函
数调用的函数内。
4969

被折叠的 条评论
为什么被折叠?



