文章目录
一、QPainter简介
QPainter 是Qt框架中的一个强大的绘图类,用于在各种设备上进行 2D 图形绘制,例如窗口、图像、打印机等。QPainter 提供了丰富的 API,可以用来绘制形状、文本、图像以及其他图形对象,还支持高级特性,比如反锯齿、透明度、渐变填充等。绘图系统基于QPainter、QPaintDevice和QPaintEngine类,QPainter是用来绘图操作的类,QPaintDevice是一个可以使用QOPainter进行绘图的抽象的二维界面,QPaintEngine给QPainter提供在不同设备上绘图的接口。QPaintEngine类由QPainter和QPaintDevice内部使用,应用程序一般无需和QPaintEngine打交道,除非要创建自己的设备类型。一般的绘图设备包括QWidget、QPixmap、QImage等,这些绘图设备为QPainter提供一个画布。
二、如何使用QPainter绘图
使用QPainter绘图步骤:
- 需要继承QWidget,然后重写painEvent方法。
- 在重写的paintEvent方法中创建一个QPainter对象。
- 设置我们绘图中需要的参数,例如笔(QPen)、画刷(QBrush)、字体(QFont)等。
- 最后调用对应的方法去绘制我们想要的图像,如直接、三角形、矩形、圆形等。
那么我们为什么一定要在重写的painEvent方法中去绘制图形呢,而不是在其他地方绘制?
- 界面更新机制:当窗口被最小化、放大、还原或被其他窗口覆盖时,窗口内容可能会丢失,因此需要重绘。Qt 会自动触发 paintEvent 来重新绘制窗口内容,而不会漏掉任何刷新请求。这种机制避免了手动管理重绘的繁琐,同时保证绘图操作的统一性。
- 确保绘图的正确顺序:paintEvent 确保所有绘图内容按照先后顺序绘制。特别是当窗口部件有多个层次的绘制需求时,paintEvent 的绘制过程由 Qt 的绘制系统管理,从而避免了绘制冲突和不一致的问题。
- Qt 使用了“脏矩形”(dirty rectangle)更新策略,即仅重绘需要更新的区域。paintEvent 会自动接收到需要更新的区域(通过 QPaintEvent 的 region() 获取),这样可以提高效率,避免不必要的重绘和资源浪费。
三、QPainter的绘图区域
QWidget的绘制区域就是其窗口的内部区域,如上图所示,是在一个QWidget窗口上绘制了一个填充矩形。在整个窗口内部的矩形区就是QPainter可绘图的区域。QWidget的内部绘图区的坐标系统如上图所示,坐标系统的单位是像素,左上角坐标为(0, 0),向右是X轴正方向,向下是Y轴正方向,绘图区的宽度由QWidget::width()函数获取,高度由QWidget::height()函数获取,所以绘图区右下角的点坐标为(width(), height())。我们使用QPainter在绘图设备上绘图,主要绘制的是一些基本的图形元素,包括点、直线、圆形、矩形、曲线、文字等,控制这些绘图元素特性的主要是QPainter的三个属性。
- QPen:它主要用于控制线条的颜色、宽度、线型等。
- QBrush:用于设置一个区域的填充特性,可以设置填充颜色、填充方式、渐变特性等,还可以采用图片做材质填充。
- QFont:用于绘制文字时,设置文字的字体样式、大小属性等。
当然除了上述的三个基本的绘图属性,还有一些其他的功能结合,比如叠加模式、旋转和缩放等功能。
以下示例代码展示了如何使用 QPainter 绘制矩形:
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this); //创建与绘图设备关联的QPainter对象
painter.setRenderHint(QPainter::Antialiasing); //启用反走样,使得绘图边缘更平滑,减少锯齿状边缘
painter.setRenderHint(QPainter::TextAntialiasing); //启用文本反走样,改善文本渲染的质量
QRect rect(this->width() / 4, this->height() / 4, this->width() / 2, this->height() / 2);
QPen pen; //设置画笔
pen.setWidth(3); //线宽
pen.setColor(Qt::red); //划线颜色
pen.setStyle(Qt::SolidLine); //线端点样式
pen.setCapStyle(Qt::FlatCap); //线的样式,实践、虚线等
pen.setJoinStyle(Qt::RoundJoin); //线的连接点样式
painter.setPen(pen);
QBrush brush;
brush.setColor(Qt::yellow); //画刷颜色
brush.setStyle(Qt::SolidPattern); //画刷填充样式
painter.setBrush(brush);
painter.drawRect(rect); //绘图
QWidget::paintEvent(event);
}
四、QPainter的常用方法
QPainter支持基本图形绘制、文本绘制、图像绘制等多种功能,并包含了高级的绘制选项,比如反锯齿、透明度、渐变填充、坐标变换等。
基本形状的绘制:
drawLine():绘制直线。
drawRect():绘制矩形。
drawEllipse():绘制椭圆。
drawPolygon():绘制多边形。
drawPath():绘制复杂路径。
文本绘制:
drawText():在指定位置绘制文本,支持设置字体、颜色等属性。
图形绘制:
drawImage():在指定位置绘制QImage对象。
drawPixmap():绘制QPixmap,适用于显示图标等小图片。
设置绘制属性:
setPen():设置绘制线条的样式、颜色、宽度等。
setBrush():设置填充图形的画刷,可以时纯色、渐变色、纹理等。
setFont():设置文本绘制的字体。
setOpacity():设置透明度。
高级功能:
抗锯齿:通过setRenderHint(QPainter::Antialiasing, true)开启抗锯齿,以获取更平滑的绘制效果。
渐变填充:支持线性渐变、径向渐变和锥形渐变,可以使用QLinearGradient、QRadialGradient等来来实现。
坐标转换:QPainter提供了平移(translate())、旋转(rorate())和缩放(scale())等方法,可以方便的对绘制的内容进行几何变化。
五、QPen的主要功能和属性
QPen 是 Qt 中用于定义绘图线条样式的类,它控制线条的颜色、宽度、线型、连接风格、端点样式等。 QPen 通常用于 QPainter,可以自定义绘制图形的边框属性,使其绘图效果更灵活和丰富。
1.设置颜色 (color)
设置绘制线条的颜色,可以使用 QColor 或标准颜色名来指定,例如 Qt::black、QColor(255, 0, 0)。
示例:
pen.setColor(Qt::blue)
2.设置宽度 (width)
设置线条的宽度,以像素为单位。默认宽度为 1。
示例:
pen.setWidth(3)
3.设置线型 (style)
设置线条样式,可以选择实线、虚线、点线等。Qt::PenStyle 枚举提供了一些预定义的样。
示例:
pen.setStyle(Qt::DashLine)
Qt::SolidLine:实线
Qt::DashLine:虚线
Qt::DotLine:点线
Qt::DashDotLine:点划线
Qt::DashDotDotLine:双点划线
4.设置端点样式 (capStyle)
设置线条的端点样式(在绘制线段时起作用),即线条的起点和终点形状。
示例:
pen.setCapStyle(Qt::RoundCap)
Qt::SquareCap:方形端点
Qt::FlatCap:平直端点
Qt::RoundCap:圆形端点
5.设置连接样式 (joinStyle)
设置线段交汇处的连接样式(适用于折线等多段线的连接点)。
> Qt::MiterJoin:尖角连接
> Qt::BevelJoin:斜角连接
> Qt::RoundJoin:圆角连接
示例:
```cpp
pen.setJoinStyle(Qt::RoundJoin)
**6.设置虚线模式 (dashPattern)**
对于自定义虚线,可以通过 setDashPattern() 设置虚线的具体模式,传入一个 QVector<qreal> 来定义虚线和间隔的交替长度。
示例:
```cpp
pen.setDashPattern({3, 5}); // 表示绘制3个像素线段,间隔5个像素。
下面是一个完整示例,展示如何创建并设置 QPen 以绘制不同风格的线条:
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPen pen;
pen.setColor(Qt::red);
pen.setWidth(5);
pen.setStyle(Qt::DashDotLine);
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
painter.setPen(pen);
painter.drawLine(10, 10, 200, 10);
// 绘制另一个线条
pen.setColor(Qt::blue);
pen.setStyle(Qt::DotLine);
painter.setPen(pen);
painter.drawLine(10, 30, 200, 30);
QWidget::paintEvent(event);
}
六、QBrush的主要功能和属性
QBrush 是 Qt 中的填充工具类,用于定义图形的填充模式(即画刷样式),可填充纯色、渐变色、纹理、图案等。QBrush 在绘制形状时可以配合 QPainter 使用,以设置形状内部的填充效果。
1.设置填充颜色 (color)
QBrush 可以使用纯色填充图形区域。可以通过 QColor 或颜色名称(如 Qt::red)来定义填充颜色。
示例:
QBrush brush(Qt::blue)
2.设置填充样式 (style)
QBrush 提供了丰富的填充样式,
常用的样式包括:
Qt::SolidPattern:实心填充。
Qt::NoBrush:无填充,区域将保持透明。
Qt::Dense1Pattern 到 Qt::Dense7Pattern:不同密度的点状填充。
Qt::HorPattern / Qt::VerPattern:水平或垂直线条填充。
Qt::CrossPattern / Qt::DiagCrossPattern:十字交叉或对角交叉线条填充。
Qt::LinearGradientPattern、Qt::RadialGradientPattern、Qt::ConicalGradientPattern:渐变填充。
示例:
brush.setStyle(Qt::Dense4Pattern)
3.设置渐变填充 (QGradient)
QBrush 支持渐变色填充,可以创建线性渐变(QLinearGradient)、径向渐变(QRadialGradient)和锥形渐变(QConicalGradient)。可以设置渐变的起点、终点以及多种颜色,从而实现平滑的颜色过渡。
示例:
QLinearGradient gradient(0, 0, 100, 100);
gradient.setColorAt(0, Qt::red);
gradient.setColorAt(1, Qt::blue);
QBrush brush(gradient);
4.设置纹理填充 (QPixmap)
QBrush 支持使用图像纹理填充,即通过 QPixmap 对象指定纹理图案,可以将图案作为填充效果应用到图形上。
示例:
QPixmap texture(":/images/pattern.png");
QBrush brush(texture);
5.设置透明度
QBrush 的透明度可以通过 QColor 的 alpha 值或渐变的透明设置来控制,以创建半透明效果的填充。
示例:
QBrush brush(QColor(0, 255, 0, 128)); // 半透明绿色
以下示例展示了如何使用不同的 QBrush 填充样式绘制矩形和椭圆:
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
// 实心填充
QBrush solidBrush(Qt::blue, Qt::SolidPattern);
painter.setBrush(solidBrush);
painter.drawRect(10, 10, 100, 100);
// 渐变填充
QLinearGradient gradient(0, 0, 100, 100);
gradient.setColorAt(0, Qt::red);
gradient.setColorAt(1, Qt::yellow);
QBrush gradientBrush(gradient);
painter.setBrush(gradientBrush);
painter.drawEllipse(120, 10, 100, 100);
// 纹理填充
QPixmap texture("./cat.jpg");
QBrush textureBrush(texture);
painter.setBrush(textureBrush);
painter.drawRect(230, 10, 100, 100);
// 点状填充
QBrush denseBrush(Qt::green, Qt::Dense3Pattern);
painter.setBrush(denseBrush);
painter.drawEllipse(350, 10, 100, 100);
QWidget::paintEvent(event);
}
七、QFont的主要功能和属性
QFont 是 Qt 中用于设置文本字体的类,可以定义字体的家族、样式、大小等。它在绘制文本时通常与 QPainter 搭配使用,使开发者能够精确控制文本的外观。
1.设置字体家族 (family)
设置字体的家族名称,例如 “Arial”、“Times New Roman”、“Courier” 等,具体可选的字体家族取决于系统上已安装的字体。
示例:
font.setFamily("Arial")
2.设置字体大小 (pointSize 和 pixelSize)
字体大小可以通过点大小(point size)或像素大小(pixel size)来设置。setPointSize() 以点为单位,而 setPixelSize() 以像素为单位。
示例:
font.setPointSize(12); // 设置字体为 12 点大小
font.setPixelSize(20); // 设置字体为 20 像素大小
3.设置字体加粗 (bold)
通过设置 setBold(true) 可以使字体加粗。
示例:
font.setBold(true);
4.设置字体为斜体 (italic)
通过 setItalic(true) 将字体设置为斜体。
示例:
font.setItalic(true);
5.设置字体下划线 (underline)
通过 setUnderline(true) 在字体下方添加下划线。
示例:
font.setUnderline(true);
6.设置字间距 (letterSpacing)
设置字符之间的间距,可以通过 setLetterSpacing() 增加或减少字母之间的距离。常见单位为像素。
示例:
font.setLetterSpacing(QFont::AbsoluteSpacing, 2); // 增加 2 像素的字间距
7.设置字重 (weight)
QFont 提供多种预定义的字重(粗细),如 QFont::Thin、QFont::Light、QFont::Normal、QFont::Bold 等,通过 setWeight() 进行设置。
示例:
font.setWeight(QFont::Bold);
8.设置字体间距 (spacing)
设置字体的间距缩放因子,可以通过 setStretch() 方法调整字体宽度的百分比(默认 100%)。
示例:
font.setStretch(150); // 设置字体宽度为原来的 150%
9.字体大写转换 (capitalization)
设置字体的字母转换方式,通过 setCapitalization() 可指定不同的大写样式,如全部大写、小写字母等。
QFont::MixedCase:混合大小写(默认)
QFont::AllUppercase:全部大写
QFont::AllLowercase:全部小写
QFont::SmallCaps:小型大写字母
示例:
font.setCapitalization(QFont::AllUppercase);
10.设置字体样式策略 (StyleStrategy)
定义字体的渲染策略,比如抗锯齿、默认样式、强制替代字体等。
示例:
font.setStyleStrategy(QFont::PreferAntialias);
下面是一个简单的示例,展示了如何使用 QFont 设置字体,并用 QPainter 绘制文本:
QPainter painter(this);
QFont font;
font.setFamily("Times New Roman");
font.setPointSize(14);
font.setBold(true);
font.setItalic(true);
font.setUnderline(true);
font.setLetterSpacing(QFont::AbsoluteSpacing, 2);
font.setCapitalization(QFont::AllUppercase);
painter.setFont(font);
painter.drawText(10, 50, "Hello, QFont!");
QWidget::paintEvent(event);
标签:Qt,填充,示例,2D,设置,绘制,QPainter
From: https://blog.csdn.net/TechNomad/article/details/143251802