一、QPainter简介

  • QPainter是Qt的二维绘图,得到的图形是不可交互的
  • 画布:​一般的绘图设备包括QWidget、QPixmap、QImage等,这些绘图设备为QPainter提供了一个“画布”,QPainter可以在这些设备上进行绘图


QPaintDevice、QPaintEngine类

  • QPaintDevice是一个可以使用QPainter进行绘图 的抽象的二维界面
  • QPaintEngine给QPainter提供在不同设备上绘图的接口

QPaintEngine类由QPainter和QPaintDevice内部使用,应用程序一般无需和QPaintEngine打交道,除非要创建自己的设备类型


二、paintEvent()、repaint()函数


paintEvent()函数 

void paintEvent(QPaintEvent *event);

Qt:45---QPainter绘图_二维

  • 从QWidget类继承的类都有paintEvent()事件,要在设备上绘图,只需要重写此事件函数,并在函数内编写相应的绘图代码就可以了



repaint()函数

  • paintEvent()函数会在应用程序启动之后执行一次,但是如果我们的绘图时的某些参数变化了,那么就需要重新绘制图片了。在指定的场景调用此函数的话,paintEvent()函数就会重新再执行一醒


三、绘图的区域

  • 左上角为坐标系的起点,向右为x轴正方向,向下为y轴的正方向
  • QWidget::width()函数可以获取绘图区的宽度。QWidget::height()函数可以获取绘图区的高度
  • 视口和窗口:绝对此次QPainter绘图的区域范围,见文章:​​

Qt:45---QPainter绘图_应用程序_02

四、QPainter绘图的属性

使用下面的一些绘图工具来配合QPainter对象完成绘图,当然还有一些其他的功能结合使用,比如叠加模式、旋转、缩放等

  • pen属性:​是一个QPen对象,用于控制线条的颜色、宽度、线型等
  • brush属性:​是一个QBrush对象,用于设置一个区域的填充特性
  • font属性:​是一个QFont对象,用于绘制文字时,设置文字的字体样式、大小等属性

QPen、QBrush、QFont见文章

五、相关函数

begin(); //开启本次QPainter绘图(开启不是开始)
end(); //结束本次QPainter绘图
setPen(); //设置画笔,
setFont(); //设置字体格式
setBrush(); //设置画刷
setRenderHint(QPainter::Antialiasing); //设置反锯齿
//设置组合模式,即后面绘制的图与前面绘制的图叠加模式,参数是一个QPainter::CompositionMode枚举类型(类型很多,有40多种,详情见QT帮助文档)
void QPainter::setCompositionMode(CompositionMode mode)

//此函数的一个演示案例,见文章:
  • 其他函数,见其他知识点

六、QPainter绘制基本图形元件

  • QPainter提供了许多绘制基本图形的功能,包括:直线、椭圆、矩形等。由这些基本的图形可以构成复杂的图形


基本图形元件

  • 下面的W、H分别代表我们绘图区的宽度和高度

QPainter painter(this);
int W=this->width();
int H=this->height();

Qt:45---QPainter绘图_二维_03Qt:45---QPainter绘图_ide_04Qt:45---QPainter绘图_QPainter绘图_05Qt:45---QPainter绘图_QPainter绘图_06Qt:45---QPainter绘图_QPainter绘图_07

  • drawLine(); //画一条线
  • drawImage(); //绘出一个图片


七、QPainterPath的使用

  • 在上面的基本图形元件中,一般的图形元件的绘制都比较简单和直观,但是​drawPath()函数​是绘制一个​复合的图形对象​,它使用​QPainterPath类型​的参数作为绘图对象

drawPath()函数的原型是:

Qt:45---QPainter绘图_应用程序_08


QPainterPath特点与如何使用

  • QPainterPath是一系列绘图操作的顺序集合,便于重复使用
  • 一个QPainterPath由许多基本的绘图操作组成,如绘图点移动、划线、画圆、画矩形等,一个闭合的QPainterPath是终点和起点​连接起来的绘图路径
  • 优点:​绘制某些复杂形状时只需创建一个QPainterPath,然后调用QPainter::drawPath()就可以重复使用
  • 例如:​绘制一个复杂的星星图案需要多次调用lineto()函数,但是定义一个QPainterPath类型的变量path记录这些绘图过程,在调用drawPath(path)就可以完成星型团的绘制



相关函数:

//将当前位置移动到(x, y)并启动一个新的子路径,隐式地关闭前一个路径

void QPainterPath::moveTo(const QPointF &point)
void QPainterPath::moveTo(qreal x, qreal y)
//从当前位置到点(x, y)绘制一条线

void QPainterPath::lineTo(const QPointF &endPoint)
void QPainterPath::lineTo(qreal x, qreal y)
//关闭当前子路径,方法是在子路径的开始处画一条线,自动启动一个新路径。新路径的当前点是(0,0)
void QPainterPath::closeSubpath()

//将给定路径的最后一个元素添加到给定路径的第一个元素,从而将给定路径与此路径连接起来
void QPainterPath::connectPath(const QPainterPath &path)
//将给定文本作为从提供的字体创建的一组封闭子路径添加到此路径。子路径的位置使文本基线的左端位于指定的点

void QPainterPath::addText(const QPointF &point, const QFont &font, const QString &text)
void QPainterPath::addText(qreal x, qreal y, const QFont &font, const QString &text)

Qt:45---QPainter绘图_二维_09


  • QPainterPath提供了很多函数可以添加各种基本图形元件的绘制,其功能与QPainter提供的绘制基本图形的功能类似,也有一些用于QPainterPath的专用函数,如closeSubpath()、connectPath()等



演示案例:


八、演示案例

Qt:45---QPainter绘图_QPainter绘图_10

  • 在类中重新声明paintEvent()函数(Q_DECL_OVERRIDE宏表示这个函数是对复函数虚函数的重载)
class Widget : public QWidget
{
protected:
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
};
  • 构造函数
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setPalette(QPalette(Qt::white));//设置窗口为白色背景
setAutoFillBackground(true);
}
  • 实现paintEvent()函数
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::TextAntialiasing);

int W=this->width(); //绘图区的宽
int H=this->height(); //绘图区的高
QRect rect(W/4,H/4,W/2,H/2);//中间区域矩形框

//设置画笔
QPen pen;
pen.setWidth(3);
pen.setColor(Qt::red);
pen.setStyle(Qt::SolidLine);
pen.setCapStyle(Qt::FlatCap);
pen.setJoinStyle(Qt::BevelJoin);

//设置画刷
QBrush brush;
brush.setColor(Qt::yellow);
brush.setStyle(Qt::SolidPattern);

//设置painter对象的画笔和画刷属性
painter.setPen(pen);
painter.setBrush(brush);

//开始绘制矩形(rect)
painter.drawRect(rect);
}