简单概述 qgraphics 绘图系统
QPainter绘图系统
组件
QPainter:用于执行绘图操作,QPainter::setPen(const QPen&)设置画笔,QPainter::setBrush(const QBrush&)设置填充,QPainter::setFont(const QFont)设置字体QPaintDevice:二维空间的抽象层,QPainter绘图的画布QPaintEngine:提供了统一设备绘图接口,由QPainter和QPaintDevice内部调用
事件
QWidget::paintEvent(QPaintEvent*):QWidget的绘图事件,QWidget::update()与QWidget::repaint(),触发此事件
坐标系统
物理坐标:
QPaintDevice基本的坐标系,以左上角为原点,xy轴向右与下递增,单位为像素逻辑坐标:由物理坐标变换而来,一般中心点为原点,xy轴向右与下递增,单位没有实际意义
视口坐标系:
QPaintDevice中以物理坐标为基础的矩形绘图区域窗口坐标系:
QPaintDevice中以逻辑坐标为基础的矩形区域,与视口坐标系的矩形为同一个

左边为视口坐标系,右边窗口坐标系,窗口坐标系使得无论 widget 的缩放,其逻辑坐标保持一致,便于绘图
QGraphics绘图体系
更高级的图形视图框架,特别对于大规模的图形项渲染较快
组件
QGraphicsItem:基本的图形项,自定义图形项要实现QGraphicsItem::paint(QPainter *, const QStyleOptionGraphicsItem*, QWidget*)绘图,和QGraphicsItem::boundingRect()绘图区域,qt本身已经实现了一些图形项
QGraphicsScene:QGraphicsItem的容器,可以附加到多个视图中QGraphicsView:用于显示QGraphicsScene,提供滚动条QGraphicsItem:基本的图形项
坐标系统
- 图形项坐标:如图所示,中心为原点,单位为像素,不会随着 widget 放缩
- 图形项在父坐标系的位置是其中心点在父坐标系的位置
- 未设置父图形项的子图形项为顶层图形项,父坐标系为场景坐标系
- 类内部操作时,一般只需考虑局部坐标,
QGraphicsItem::pos()QGraphicsItem::setPos()例外,返回父坐标中的位置
- 场景坐标:如图所示,用于确定顶层图形项的位置,单位为像素,不会随着 widget 放缩
- 视图坐标:如图所示,widget 的物理坐标,与场景和图形项坐标无关,需要通过坐标映射之后再操作

在需要用到不同 item 的坐标时,一定要用 mapxx函数来 统一坐标系。
布局
函数原型省去了部分元素,具体参见文档
QGraphicsView::sceneRect():视图中的场景的可视化范围。当视图小于场景时,只对QGraphicsView::sceneRect内的图像生成滚动条,之外的图像将不能被显示- 计算对齐方式时,会以
QGraphicsView::sceneRect为标准 - 默认与
QGraphicsScene::sceneRect(两者不同)具有相同的值,并且随之变化(未设置的话)
- 计算对齐方式时,会以
QGraphicsScene::sceneRect():场景的边界矩形,用于管理图形项- 如果设置了
QGraphicsView::sceneRect,那么QGraphicsScene::sceneRect与视图的显示无关,超出边界的item也可能被显示出来
- 如果设置了
QGraphicsItem::boundingRect():图形项的边界矩形。QGraphicsView通过它来重绘图形项,所以所有绘图内容必须在其内。不受图形项变换的影响QGraphicsItem::shape():返回图形项的形状,由QGraphicsItem::contains()和QGraphicsItem::collidesWithPath()的默认调用实现碰撞检测,命中等

QGraphicsItem::zValue():图形项的堆叠顺序,0为顶层
QGraphicsItem父子关系
父item属性改变,子item也会跟着改变,如enable,visible父item会传播位置改变和transform给子item,即子跟着父移动,变换绘图顺序:先绘制
父item,再绘制子item子item的stack order默认在父item之前,为子item设置ItemStacksBehindParent,可以改变这个顺序
QGraphicsItem场景事件
QGraphicsScene将事件打包传递给子item,注意父item不会过滤掉子item的事件,除非设置了QGraphicsItem::setFiltersChildEvents(bool),事件的触发与 item 的zValue和stack顺序有关
QVariant QGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value):描述了item的改变,需要设置QGraphicsItem::ItemSendsGeometryChanges才会触发hoverEnterEventhoverLeaveEventhoverMoveEvent:鼠标徘徊事件,需要setAcceptHoverEvents(true)才会触发
REFERENCE
[1]王维波, 栗宝鹃, 侯春望. Qt 5.9 C++开发指南[M]. 人民邮电出版社, 2018.
[2]QGraphicsItem Class | Qt Widgets 5.13.1[EB/OL].
文档信息
- 本文作者:wzx
- 本文链接:https://wzx140.github.io//2019/09/08/qt-graphics/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)