文章目录
Graphics View Framework的介绍
Qt Graphics View Framework是Qt提供的一套用来绘制和管理复杂的、大量2D图形的架构。该框架包含一个事件传播架构,能够为场景中的图形项提供精确的双精度交互功能。图形项可以处理键盘事件、鼠标按下、移动、释放和双击事件,同时还可以跟踪鼠标的移动。Graphics View框架使用BSP树来实现对图形项的快速查找,即使在包含数百万个图形项的情况下也能够实时地可视化大规模的场景。Graphics View Framework非常适合用于开发图表、流程图、绘图程序、游戏界面等需要大量图形操作的应用。
Graphics View Framework主要有三个核心类组成:QGraphicsView、QGraphicsScene、QGraphicsItem,三者是高度解耦的
| 类名 | 说明 |
|---|---|
| QGraphicsView | 视图类,负责将场景内容渲染到屏幕上,并处理用户的交互输入(鼠标、键盘等事件) |
| QGraphicsScene | 场景类,是所有图形项(Items)的容器, 提供坐标系统和管理功能: 为大量图形项提供快速管理接口,传递事件到每个图形项,管理每个图形项的状态(如选择和聚焦操作等),提供未变换的渲染功能,主要用于打印 |
| QGraphicsItem | 图元类,是所有图形项的基类,可以是矩形、椭圆、文本、路径和自定义的复杂图形项 |
QGraphicsView视图
QGraphicsView是一个可视化的视图控件,可以通过调用setScene或者向QGraphicsView构造函数传递scene来显示场景中的内容,多个视图可以关联到同一个场景,即同一个场景中的数据集可以用多个视图显示。视图控件是一个滚动区域,在显示大场景时可以通过滚动条实现。
view是通过调用render()函数实现scene的可视化。默认情况下,item是使用普通的QPainter绘制到视图窗口上的,并且使用了默认的渲染提示,如果想更改QGraphicsView在绘制图形项时传递给QPainter的默认渲染提示,可以调用setRenderHints()函数。渲染提示是通过QPainter::RenderHint枚举设置的,用于控制绘图时的质量和性能之间的平衡,不同的渲染提示会影响图形绘制方式,同时对渲染性能产生直接影响。
| Render Hint | 描述 |
|---|---|
| QPainter::Antialiasing | 抗锯齿,边缘更平滑,会增加 CPU/GPU 计算量 |
| QPainter::TextAntialiasing | 文本抗锯齿。改善文本的视觉质量 |
| QPainter::SmoothPixmapTransform | 使用像素图变换算法(如双线性插值算法)而不是最邻近算法,提升图像缩放和旋转的质量 |
| QPainter::NonCosmeticBrushPatterns | 默认画笔是否为“非装饰性”,图案被视为普通图形的一部分,会随着变换一同缩放、旋转、剪切 |
| QPainter::VerticalSubpixelPositioning | 允许文本在水平和垂直方向上都以亚像素精度进行定位。对于大多数使用场景来说,开启此功能不会明显提升视觉质量,但可能会增加内存消耗,并导致文本渲染性能略有下降 |
| QPainter::LosslessImageRendering | 在可能的情况下,使用无损图像渲染 |
QGraphicsView接收鼠标和键盘事件,并将这些事件传递给场景中的事件。通过其变换矩阵 QGraphicsView::transform(),QGraphicsView 可以对场景的坐标系进行变换。这使得视图可以实现高级的导航功能,例如缩放和旋转。为了方便使用,QGraphicsView 还提供了用于在视图坐标与场景坐标之间进行转换的函数:QGraphicsView::mapToScene()和QGraphicsView::mapFromScene()。
平移、旋转和缩放功能的实现
QGraphicsView 支持使用 QTransform 进行仿射变换。你可以将一个变换矩阵传入 setTransform(),或者调用一些便捷函数如 rotate()、scale()、translate() 或 shear()。最常见的两种变换是缩放(用于实现缩放功能)和旋转。在进行变换时,QGraphicsView 会保持视图的中心不变。由于场景对齐方式(通过 setAlignment() 设置),平移视图可能不会产生视觉上的变化。我们可以通过改变视图的滚动条位置实现视图区域的拖拽,也可以通过设置view的拖拽模式实现(不能重载mouseMoveEvent函数):setDragMode(QGraphicsView::ScrollHandDrag)。
鼠标移动操作实现视图区域的拖拽代码示例:
void View::mouseMoveEvent(QMouseEvent* event)
{
if (event->buttons() & Qt::LeftButton) {
auto deltaPos = event->pos() - _pressedPoint; // _pressedPoint为鼠标按下时记录的点位
_pressedPoint = event->pos();
auto hBar = this->horizontalScrollBar();
auto vBar = this->verticalScrollBar();
hBar->setValue(hBar->value() - deltaPos.x());
vBar->setValue(vBar->value() - deltaPos.y());
}
}
鼠标缩放视图的实现代码示例:
void View::wheelEvent(QWheelEvent* event)
{
QPoint numDegrees = event->angleDelta() / 8;
if (!numDegrees.isNull()) {
QPoint numStep = numDegrees / 15;
const double scaleFactor = 1.2;
/*使用scale()函数实现缩放*/
//numStep.y() > 0 ? this->scale(scaleFactor, scaleFactor) : this->scale(1 / scaleFactor, 1 / scaleFactor);
/*使用QTransform实现缩放*/
QTransform matrix = this->transform();
numStep.y() > 0 ? matrix.scale(scaleFactor, scaleFactor) : matrix.scale(1 / scaleFactor, 1 / scaleFactor);
this->setTransform(matrix);
}
}
鼠标和键盘的交互
可以使



被折叠的 条评论
为什么被折叠?



