QPainter基础:从创建到实战

各位同学好,我是老张。今天咱们来聊聊QPainter——Qt绘图系统的核心角色。说实话,我刚开始接触Qt时,觉得绘图这事儿挺神秘的。后来做项目多了才发现,QPainter其实就是个"画师",你给它指令,它就在画布上干活。

QPainter的创建与销毁

QPainter的使用有个铁律:必须在paintEvent里创建,用完就销毁。为什么?因为绘图资源很宝贵,系统不允许你随便乱画。

核心原则:QPainter的生命周期严格绑定在paintEvent中,不要试图在其他地方创建并使用它。

来看个标准写法:

void MyWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);  // 创建,指定画布为当前窗口
    // ... 绘图操作 ...
}  // 析构函数自动调用,painter自动销毁

嗯,这里有个细节:QPainter painter(this)这行代码,括号里的this就是画布。可以是QWidget、QPixmap、QImage等。我个人习惯用QPixmap做双缓冲,后面会讲到。

我曾经踩过的坑:在paintEvent外部创建QPainter,结果程序直接崩溃。后来查文档才知道,QPainter只能在paintEvent里用,这是Qt的设计约束。

销毁呢?其实不用你操心。QPainter的析构函数会自动调用end(),释放资源。但如果你用new创建了指针,记得手动delete。不过说实话,我几乎不用new来创建QPainter,栈上创建最安全。

QPainter的常用设置

画师有了,接下来得给他配工具。QPainter有三件套:画笔(QPen)、画刷(QBrush)、字体(QFont)。

画笔(QPen)

画笔负责画轮廓线。你可以设置颜色、宽度、样式等。看代码:

QPainter painter(this);

QPen pen;
pen.setColor(Qt::red);          // 红色
pen.setWidth(3);                // 线宽3像素
pen.setStyle(Qt::DashLine);     // 虚线样式
painter.setPen(pen);

painter.drawLine(10, 10, 100, 10);  // 画一条红色虚线

样式有哪些?我列个表:

枚举值 效果 适用场景
Qt::SolidLine 实线 默认,最常用
Qt::DashLine 虚线 辅助线、标注
Qt::DotLine 点线 极细的辅助线
Qt::DashDotLine 点划线 中心线、轴线

我在项目中遇到过一个问题:画虚线时,如果线宽太大,虚线效果会失真。后来发现是pen.setCapStyle()没设置对,改成Qt::RoundCap就好了。

画刷(QBrush)

画刷负责填充区域。颜色、渐变、纹理都可以。举个例子:

QBrush brush;
brush.setColor(QColor(100, 200, 100));  // 浅绿色
brush.setStyle(Qt::SolidPattern);       // 实心填充
painter.setBrush(brush);

painter.drawRect(20, 20, 80, 60);       // 画一个填充的矩形

画刷样式也很多:

  • SolidPattern:纯色填充,最常用
  • Dense1Pattern ~ Dense7Pattern:不同密度的点阵
  • HorPattern / VerPattern:水平/垂直线条
  • CrossPattern:交叉网格
  • LinearGradientPattern:线性渐变
  • RadialGradientPattern:径向渐变

小技巧:如果你需要渐变填充,直接用QLinearGradient或QRadialGradient创建画刷,效果更细腻。我做过一个仪表盘项目,用径向渐变模拟金属质感,效果很棒。

字体(QFont)

绘图时经常要写文字。字体设置很简单:

QFont font;
font.setFamily("Microsoft YaHei");  // 字体
font.setPointSize(14);              // 字号
font.setBold(true);                 // 加粗
painter.setFont(font);

painter.drawText(50, 50, "Hello Qt!");  // 绘制文字

注意:drawText的坐标是文字左下角的位置。如果你想让文字居中,可以用drawText(rect, Qt::AlignCenter, text)。

坐标系统与变换

坐标系统是绘图的基石。QPainter默认的坐标原点在左上角,x轴向右,y轴向下。但你可以通过变换来改变它。

平移(translate)

把原点挪到别处。比如你想以窗口中心为原点画图:

painter.translate(width() / 2, height() / 2);  // 原点移到中心

旋转(rotate)

绕原点旋转。角度单位是度,顺时针为正:

painter.rotate(45);  // 顺时针旋转45度

缩放(scale)

放大或缩小。参数是缩放因子:

painter.scale(2.0, 1.5);  // x方向放大2倍,y方向放大1.5倍

保存与恢复状态

这个很重要!变换会影响后续所有绘图。所以变换前要保存状态,画完再恢复:

painter.save();      // 保存当前状态
painter.translate(100, 100);
painter.rotate(30);
// 画图...
painter.restore();   // 恢复状态

我曾经犯过的错:画一个旋转的矩形,结果后面的所有图形都跟着转了。就是因为忘了save/restore。后来养成习惯:每次变换前先save,画完立刻restore。

知识体系总览

下面这张图概括了本章的核心内容:

QPainter 基础 创建与销毁 常用设置 坐标系统与变换 paintEvent内创建 析构自动销毁 QPen QBrush QFont translate rotate scale save/restore 核心:paintEvent内创建 → 设置三件套 → 变换 → 绘图 → 自动销毁

说白了,QPainter的使用流程就是:创建 → 设置 → 变换 → 绘图 → 销毁。每一步都有讲究,但掌握了这些基础,你就能画出大部分想要的图形了。

我的建议:刚开始学的时候,别急着搞复杂效果。先画个矩形、写行文字,感受一下坐标系统。等你熟练了,再玩渐变、变换这些高级功能。

好了,这一章就到这里。记住:多动手写代码,光看是学不会绘图的。下一章我们聊聊QPainter的绘图API,包括画线、画矩形、画椭圆这些基本操作。

可可精品资料库