Qt中提供了强大的2D绘图系统,可以使用相同的API在屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice和QPaintEngine这三个类。
一个定制化的完美产品,从来都不仅仅是利用库中现有的控件来完成,2D绘图给我们提供了专用定制化的平台,这就是创意的开始。 QPaintDevice是一个绘制设备。 是一个二维空间的抽象, 是所有可以绘制对象的基类, 包括QWidget QPicture QPrinter等。
QPainter提供高度优化的功能来完成大多数绘图GUI程序的要求。它可以绘制从简单的线条到复杂的形状,如线和弦。它也可以绘制对齐的文本和像素图片。通常情况下是在一个常规坐标系中进行绘制,但也可以进行窗口——视口变换。QPainter可以在任何继承了QPaintDevice类的对象上运行。
可以把QPainter想象成一个画笔,开发人员拿着画笔理论上是可以绘制任何你想要的图形,前提是你绘画功底足够(逻辑+算法)。
QPainter 一般在一个部件(widget)重绘事件( PaintEvent )的处理函数paintEvent ()中进行绘制,首先要创建QPainter 对象(画笔),然后进行图形的绘制, 最后销毁QPainter 对象。
QPainter的核心功能是绘图,但该类还提供了几个功能,允许您自定义QPainter的设置及其渲染质量。另外,通过指定QPainter的构图模式,您可以控制如何将不同的形状合并在一起。
在QPainter中提供了一些方便的函数来绘制常用的图形,而且还可以设置线条和边框的画笔以及进行填充的画刷。
例如绘制一条直线:
在widget.h文件中声明重绘事件处理函数:
protected:
void paintEvent(QPaintEvent *event);
在widget.cpp文件中对paintEvent()函数进行如下定义:
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawLine(QPoint(0, 0), QPoint(100, 100));
}
这里指定了this为绘图设备,即表明在该部件上进行绘制。使用这个构造函数创建的对象会立即开始在设备上进行绘制,它会自动调用begin()函数,然后在QPainter的析构函数中调用end()函数结束绘制。如果在构建QPainter对象时不想指定绘制设备,那么可以使用不带参数的构造函数:
QPainter painter;
painter.begin(this);
painter.drawLine(QPoint(0, 0), QPoint(100, 100));
painter.end();
drawLine()
该函数绘制了一条线段,这里使用了该函数的一种重载形式QPainter::drawLine ( const QPoint & p1, const QPoint & p2 )其中p1和p2分别是线段的起点和终点。这里的QPoint(0, 0)就是窗口的原点,默认是窗口的左上角(不包含标题栏)。
函数 |
功能 |
drawArc() |
绘制圆弧 |
drawChord() |
绘制弦 |
drawConvexPolygon() |
绘制凸多边形 |
drawEllipse() |
绘制椭圆 |
drawLine() |
绘制线条 |
drawPie() |
绘制扇形 |
drawPoint() |
绘制点 |
drawPolygon() |
绘制多边形 |
drawPolyline() |
绘制折线 |
drawRect() |
绘制矩形 |
drawRoundedRect() |
绘制圆角矩形 |
drawArc()——弧(演示[0])
drawChord()—— 弦
drawConvexPolygon()—— 凸多边形
drawEllipse()——椭圆
drawImage()—— QImage表示的图像
drawLine()——线(演示[0] )
drawLines()—— 多条线
drawPath()——路径
drawPicture()—— 按QPainter指令绘制
drawPie()——扇形
drawPixmap()——QPixmap表示的图像
drawPoint()—— 点
drawPoints()——多个点
drawPolygon()——多边形
drawPolyline()——多折线
drawRect()—— 矩形(演示[0])
drawRects()—— 多个矩形
drawRoundRect()——圆角矩形
drawText()—— 文字
drawTiledPixmap()—— 平铺图像
drawLineSegments()—— 绘制折线
QPen定义了用于QPainter应该怎样画线或者轮廓线。画笔具有样式style() 、宽度width() 、画刷brush() 、笔帽样式capStyle()和连接样式joinStyle()等属性。
这么多参数既可以在构造时指定,也可以使用 set 函数指定,完全取决于你的习惯。使用setWidth(),setBrush(),setCapStyle()和setJoinStyle()函数可以轻松修改各种设置(注意画笔的笔必须在更改笔的属性时重置)。
其中Qt::SquareCap风格表示线条的终点为方形,并且向前延伸了线宽的一半的长度;而Qt::FlatCap风格也是方形端点,但并没有延长;使用Qt::RoundCap风格的线条是圆形的端点,这些风格对宽度为0的线条没有作用。
其中Qt::BeveJoin风格填充了两个线条之间的空缺三角形;而Qt::RoundJoin是使用圆弧来填充这个三角形,这样显得更圆滑;使用Qt::MiterJoin风格,是将两个线条的外部边线进行扩展而相交,然后填充形成的三角形区域。这三种风格对于宽度为0的线条没有作用。
QPainter::drawArc ( const QRectF & rectangle, int startAngle, int spanAngle )
这里的三个参数分别对应于需要指定弧线所在的矩形、起始角度和跨越角度。
// 创建画刷
QBrush brush(QColor(0, 0, 255), Qt::Dense4Pattern);
// 使用画刷
painter.setBrush(brush);
// 绘制椭圆
painter.drawEllipse(220, 20, 50, 50);
// 设置纹理
brush.setTexture(QPixmap("image.png"));
// 重新使用画刷
painter.setBrush(brush);
// 定义四个点
static const QPointF points[4] = {
QPointF(270.0, 80.0),
QPointF(290.0, 10.0),
QPointF(350.0, 30.0),
QPointF(390.0, 70.0)
};
// 使用四个点绘制多边形
painter.drawPolygon(points, 4);
运行结果:
QBrush 类提供了画刷来对图形进行填充, 一个画刷具有
QBrush样式()使用Qt :: BrushStyle枚举定义填充模式。默认的风格是Qt :: NoBrush(取决于你如何构建画笔),不填充形状。标准的填充风格是Qt :: SolidPattern。设置画刷的方式有两种,一种是利用构造函数,另外一种是利用setstyle函数。
在Qt中使用的颜色一般都由QColor类来表示,它支持RGB、HSV和CMYK等颜色模型。QColor还支持基于alpha的轮廓和填充(实现透明效果),而且QColor类与平台和设备无关(颜色使用QColormap类向硬件进行映射)。在Qt中还提供了20种预定义的颜色,比如我们以前经常使用的Qt::red等 。
填充模式使用Qt::BrushStyle枚举变量来定义,包含了基本模式填充、渐变填充和纹理填充。
笔刷颜色(color)定义了填充图案的颜色。颜色可以是Qt的预定义颜色之一,Qt :: GlobalColor或任何其他自定义QColor。可以分别使用color()和setColor()函数获取和更改当前设置的颜色。
QGradient类就是用来和QBrush一起指定渐变填充的。Qt现在支持三种类型的渐变填充:
这三种渐变分别由QGradient的三个子类来表示,QLinearGradient表示线性渐变,QRadialGradient表示辐射渐变,QConicalGradient表示锥形渐变。
QLinearGradient::QLinearGradient ( const QPointF & start, const QPointF & finalStop )
QRadialGradient::QRadialGradient ( const QPointF & center, qreal radius, const QPointF & focalPoint )
QConicalGradient::QConicalGradient ( const QPointF & center, qreal angle )
需要指定中心点center和一个角度angle(其值在0到360之间),然后沿逆时针从给定的角度开始环绕中心点插入颜色。这里给定的角度沿逆时针方向开始的位置为0,旋转一圈后为1。
// 线性渐变
QLinearGradient linearGradient(QPointF(40, 190), QPointF(70, 190));
// 插入颜色
linearGradient.setColorAt(0, Qt::yellow);
linearGradient.setColorAt(0.5, Qt::red);
linearGradient.setColorAt(1, Qt::green);
// 指定渐变区域以外的区域的扩散方式
linearGradient.setSpread(QGradient::RepeatSpread);
// 使用渐变作为画刷
painter.setBrush(linearGradient);
painter.drawRect(10, 170, 90, 40);