目录
- 0.为什么?
- 1.绘图API核心类
- 2.设置画笔
- 3.设置画刷
- 4.设置画家
- 1.移动画家位置
- 2.保存/加载画家的状态
0.为什么?
- 虽然Qt已经内置了很多的控件,但是不能保证现有控件就可以应对所有场景,很多时候,需要更强的"定制"能力
- Qt提供了画图相关的API,可以允许用户在窗⼝上绘制任意的图形形状,来完成更复杂的界⾯设计
- 所谓的"控件",本质上也是通过画图的⽅式画上去的
- 画图API和控件之间的关系,可以类⽐成机器指令和⾼级语⾔之间的关系
- 控件是对画图API的进⼀步封装,画图API是控件的底层实现
1.绘图API核心类
QPainter
:⽤来绘图的对象,提供了⼀系列drawXXX
⽅法,可以允许用户绘制各种图形QPaintDevice
:描述了QPainter
把图形画到哪个对象上QWidget
也是⼀种QPaintDevice
(QWidget
是QPaintDevice
的⼦类)
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); }
- 上述代码现象:在画第三个圆之前,由于还原了画家的状态,所以此时画家的位置坐标会移动到画家状态保存的地⽅,所以在绘制第三个圆的位置时实际是和第⼆个圆发⽣了重叠