[Qt][绘图][上]详细讲解


0.为什么?

  • 虽然Qt已经内置了很多的控件,但是不能保证现有控件就可以应对所有场景,很多时候,需要更强的"定制"能力
  • Qt提供了画图相关的API,可以允许用户在窗⼝上绘制任意的图形形状,来完成更复杂的界⾯设计
  • 所谓的"控件",本质上也是通过画图的⽅式画上去的
    • 画图API和控件之间的关系,可以类⽐成机器指令和⾼级语⾔之间的关系
    • 控件是对画图API的进⼀步封装,画图API是控件的底层实现

1.绘图API核心类

  • QPainter:⽤来绘图的对象,提供了⼀系列drawXXX⽅法,可以允许用户绘制各种图形
  • QPaintDevice:描述了QPainter把图形画到哪个对象上
    • QWidget也是⼀种QPaintDevice(QWidgetQPaintDevice的⼦类)
  • QPen:描述了QPainter出来的线是什么样的
  • QBrush:描述了QPainter填充⼀个区域是什么样的
  • 注意:绘图API的使⽤,⼀般不会在QWidget的构造函数中使⽤,⽽是要放到paintEvent事件中
    • paintEvent会在以下情况会被触发
      • 控件⾸次创建
      • 控件被遮挡,再解除遮挡
      • 窗⼝最⼩化,再恢复
      • 控件⼤⼩发⽣变化时
      • 主动调⽤repaint()或者update()⽅法(这两个⽅法都是QWidget的⽅法)
    • 因此,如果把绘图API放到构造函数中调⽤,那么⼀旦出现上述的情况,界⾯的绘制效果就⽆法确保符合预期
  • 示例
    void Widget::paintEvent(QPaintEvent *event)
    {
        // 此处的this并不是设置父对象,而是设置画板(往哪儿画)
    	QPainter painter(this);
    }
    

2.设置画笔

  • QPainter在绘制时,是有⼀个默认的画笔的,使⽤时也可以⾃定义画笔

  • QPen类中定义了QPainter应该如何绘制形状、线条和轮廓,同时通过QPen类可以设置画笔的线宽、颜⾊、样式、 画刷

  • 画笔的颜⾊可以在实例化画笔对象时进⾏设置,画笔的宽度是通过setWidth()进⾏设置,画笔的⻛格是通过setStyle()进⾏设置,设置画刷主要是通过setBrush()

    • 设置画笔颜⾊QPen::QPen(const QColor& color)
      • 画笔的颜⾊主要是通过QColor类设置
    • 设置画笔宽度void QPen::setWidth(int width)
    • 设置画笔⻛格void QPen::setStyle(Qt::PenStyle style),有如下风格
      请添加图片描述
  • 示例

    void Widget::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
        
        QPen pen;
        pen.setColor(QColor(255, 0, 0));
        pen.setWidth(5);
        pen.setStyle(Qt::DashLine);
        
        painter.setPen(pen);
    }
    

3.设置画刷

  • 画刷是使⽤QBrush类来描述,画刷⼤多⽤于填充

    • QBrush定义了QPainter的填充模式, 具有样式、颜⾊、渐变以及纹理等属性
  • 设置画刷主要通过void QPen::setBrush(const QBrush& brush),其参数为画刷的格式

    • 画刷的格式中定义了填充的样式,使⽤Qt::BrushStyle枚举,默认值是Qt::NoBrush
      请添加图片描述
  • 示例

    void Widget::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
        
        QBrush brush;
        brush.setColor(QColor(0, 255, 0));
        brush.setStyle(Qt::CrossPattern);
        
        painter.setBrush(brush);
    }
    

4.设置画家

1.移动画家位置

  • 有时候在绘制多个图形时,想使⽤同⼀坐标位置,那么绘制出来的图形肯定会重合,此时,可以通过 移动画家的位置来使图形不发⽣重合
  • 通过使⽤translate()即可移动画家所在位置
  • 示例
    void Widget::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
        
        painter.drawEllipse(QPoint(100, 200), 100, 100);
        
        // 让画家移动
        painter.translate(200, 300);
        
        painter.drawEllipse(QPoint(100, 200), 100, 100);
    }
    

2.保存/加载画家的状态

  • 在绘制图形的过程中,可以通过save()来保存画家的状态,使⽤restore()还原画家状态
  • 示例
    void Widget::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
        
        painter.drawEllipse(QPoint(100, 200), 100, 100);
        
        painter.translate(200, 0); // 让画家移动
        
        painter.save(); // 保存画家状态
        
        painter.drawEllipse(QPoint(100, 200), 100, 100);
        
        painter.translate(200, 0); // 让画家移动
        
        painter.restore(); // 还原画家状态
        
        painter.drawEllipse(QPoint(100, 200), 100, 100);
    }
    
  • 上述代码现象:在画第三个圆之前,由于还原了画家的状态,所以此时画家的位置坐标会移动到画家状态保存的地⽅,所以在绘制第三个圆的位置时实际是和第⼆个圆发⽣了重叠

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DieSnowK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值