Qt的绘图系统允许使用相同的API在屏幕和打印设备上进行绘制。整个绘图系统基于QPainter,QPainterDevice和QPaintEngine三个类。
QPainter用来执行绘制的操作;QPaintDevice是一个二维空间的抽象,这个二维空间可以由QPainter在上面进行绘制;QPaintEngine提供了画笔painter在不同的设备上进行绘制的统一的接口。
它可以绘制一切想要的图形,从最简单的一条直线到其他任何复杂的图形,例如:点、线、矩形、弧形、饼状图、多边形、贝塞尔弧线等。
此外,QPainter 也支持一些高级特性,例如反走样(针对文字和图形边缘)、像素混合、渐变填充和矢量路径等,QPainter 也支持线性变换,例如平移、旋转、缩放。
首先简单介绍一下坐标系统:QT中的窗口都有的默认的坐标原点(0,0),位于屏幕的左上角,X轴正方向是水平向右,Y轴正方向是竖直向下,相反为负。
x:窗口左上角x坐标 y:窗口左上角y坐标 width:窗口长度 height:窗口高度
一个绘图工具的使用步骤常为:(1)构造一个绘图工具(2)设置字体、画笔、画刷等等参数(3)绘图(4)销毁绘图工具
绘制的内容会以背景的形式出现在窗口中,线和轮廓都可以用画笔QPen进行绘制,画刷QBrush进行填充,字体可以使用QFont类定义。
大量的资料在QT提供的官方文档里有介绍,也可以直接看看。
我们先来看几个常见的图像,我用的是QT5.9.0,首先在头文件中加入#include
以及声明函数protected:void paintEvent(QPaintEvent *);//重绘事件处理函数
1.绘制直线
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);//Q_UNUSED() 没有实质性的作用,用来避免编译器警告
QPainter painter(this);//this为绘图设备,即表明在该部件上进行绘制
painter.drawLine(0, 0, 200, 200);
}
2.绘制矩形
painter.drawRect(50,50,150,150);//x,y,w,h
3.绘制椭圆
painter.drawEllipse(100, 100, 100, 80); //x,y,w,h
4.绘制扇形
QRectF rect(50, 50, 500, 500);
int startAngle = 0 * 16;//扇形起始角度(0°) startAngle: 开始的角度,单位是十六分之一度
int spanAngle = 120 * 16;//扇形覆盖范围(120°) spanAngle: 覆盖的角度,单位是十六分之一度
painter.drawPie(rect, startAngle, spanAngle);//绘制圆心为包围矩形的正中心,角度的正方向是逆时针方向
坐标系变换是利用变换矩阵来进行的,我们可以利用QTransform类来设置变换矩阵,QPainter类提供了对坐标系的平移,缩放,旋转,扭曲等变换函数。
如利用translate()函数进行平移变换。其实就是改变坐标的中心。
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);//Q_UNUSED() 没有实质性的作用,用来避免编译器警告
QPainter painter(this);//this为绘图设备,即表明在该部件上进行绘制
painter.setBrush(Qt::blue);
painter.drawRect(0,0,100,100);
painter.translate(100,100); //将当前坐标系下的点(100,100)设为原点
painter.setBrush(Qt::green);
painter.drawRect(0,0,100,100);
}
利用scale()函数进行比例变换,实现放大缩小。(和css很像)
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);//Q_UNUSED() 没有实质性的作用,用来避免编译器警告
QPainter painter(this);//this为绘图设备,即表明在该部件上进行绘制
painter.setBrush(Qt::blue);
painter.drawRect(0,0,100,100);
painter.translate(100,0);//将中心移到(100,0)
painter.scale(2,2); //在x轴和y轴方向扩大2倍,小于1为缩小
painter.setBrush(Qt::green);
painter.drawRect(0,0,100,100);
}
利用rotate()函数进行翻转变换。 注意和上图的区别
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);//Q_UNUSED() 没有实质性的作用,用来避免编译器警告
QPainter painter(this);//this为绘图设备,即表明在该部件上进行绘制
painter.setBrush(Qt::blue);
painter.drawRect(0,0,100,100);
painter.translate(100,100);//将中心移到(100,100)
painter.rotate(30);//旋转30°
painter.setBrush(Qt::green);
painter.drawRect(0,0,100,100);
}
利用shear()函数就行扭曲变换。
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);//Q_UNUSED() 没有实质性的作用,用来避免编译器警告
QPainter painter(this);//this为绘图设备,即表明在该部件上进行绘制
painter.setBrush(Qt::blue);
painter.drawRect(0,0,100,100);
painter.translate(100,100);//将中心平移到(100,100)
painter.shear(0,1); //x方向保持不变,y轴发生变化
painter.setBrush(Qt::green);
painter.drawRect(0,0,100,100);
}
坐标系的保存与恢复
绘图过程中可以先利用save()函数来保存坐标系现在的状态,然后进行变换操作,操作完之后,再用restore()函数将以前的坐标系状态恢复。
void MainWindow::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);//Q_UNUSED() 没有实质性的作用,用来避免编译器警告
QPainter painter(this);//this为绘图设备,即表明在该部件上进行绘制
painter.save();
painter.translate(100,100);//将中心移到(100,100)
painter.setBrush(Qt::blue);
painter.drawRect(0,0,100,100);
painter.restore();
painter.setBrush(Qt::green);
painter.drawRect(0,0,100,100);
}