8.1.1 QPainter绘图系统
可以在QWidget内使用QPainter画图。
QWidget类及其子类是最常用的绘图设备,从QWidget类继承的类都有paintEvent()事件,要在设备上绘图,可以创建一个QPainter对象获取到绘图设备接口,然后使用该对象画图。
void QWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this); // 创建与绘图设备关联的QPainter对象
... // painter在设备的窗口上画图
}
QWidget的绘图区的宽度可由QWidget::width()函数获取(即x最大值),高度由QWidget::height()函数获取(即y最大值)。
QPainter画出的图形主要由它的3个属性控制,分别是:pen属性、brush属性、font属性。pen属性负责线条,brush属性负责区域的填充、font属性负责绘制文字。
示例:用QPainter绘制的基本流程
首先在Widget类的定义中添加 paintEvent()的声明,来重载该函数:
// 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
protected:
void paintEvent(QPaintEvent *event) override; // 重载父类里的该函数
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
然后在Widget.cpp中编写Widget类的构造函数和我们新加入的paintEvent()函数的具体内容:
// Widget.cpp
#include <QPainter>
#include <QPaintEvent>
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setPalette(QPalette(Qt::white)); // 设置窗口为白色背景
setAutoFillBackground(true);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this); // 创建QPainter对象
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); // 线的连接点样式
painter.setPen(pen); // 画笔装到painter里
QBrush brush; // 新建画刷
brush.setColor(Qt::yellow); // 画刷颜色
brush.setStyle(Qt::SolidPattern); // 画刷填充样式
painter.setBrush(brush); // 画刷装到painter里
painter.drawRect(rect);
}
其中,QRect rect创建了一个矩形框,该参数列表表示创建了一个左上角位于Widget的(W / 4, H / 4)位置,自身宽 W / 2、高H / 2的矩形。因为这个矩形的大小的定义利用了Widget的高度和宽度,所以它不是固定大小,它的大小会随着Widget的大小变化而变化。
最后一句painter.drawRect(rect)代表用painter在我们建好的rect区域里绘制。
QPen和QBrush的主要功能参见《开发指南》。
示例:在圈好的矩形框中画一个扇形
#include <QPainter>
#include <QPaintEvent>
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setPalette(QPalette(Qt::white));
setAutoFillBackground(true);
}
Widget::~Widget()
{
delete ui;
}
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::DashLine);
// pen.setCapStyle(Qt::FlatCap);
// pen.setJoinStyle(Qt::BevelJoin);
// painter.setPen(pen);
// QBrush brush;
// brush.setColor(Qt::yellow);
// brush.setStyle(Qt::HorPattern);
// painter.setBrush(brush);
// painter.drawRect(rect);
// draw Pie
QRect rect(W / 4, H / 4, W / 2, H / 2);
int startAngle = 0 * 16;
int spanAngle = 240 * 16;
painter.drawPie(rect, startAngle, spanAngle);
}
扇形会与我们圈好的rect矩形框相切,填满整个矩形。比如rect是一个长方形,我们画一个360度的扇形的话,最后它会围成一个椭圆。
QPainterPath的使用