QGraphicsView是Qt图形视图框架中的一个重要类,它提供了一个窗口部件,用于显示QGraphicsScene中的内容。QGraphicsView充当了视图的角色,可以将场景中的2D图形项渲染到屏幕上,并支持用户与这些项的交互。以下是QGraphicsView的关键特性和使用方法的详细介绍:
关键特性
- 视图与场景分离:QGraphicsView与QGraphicsScene分离,允许一个场景被多个视图观察,每个视图都可以有自己的视角和变换。
- 视口与坐标系统:QGraphicsView内部有一个视口,它映射的是场景的部分或全部内容。视口的坐标系统与场景的坐标系统不同,但可以通过变换矩阵相互转换。
- 交互功能:QGraphicsView支持丰富的交互功能,如平移、缩放、旋转,用户可以通过鼠标和键盘操作来改变视图的显示。
- 滚动条:QGraphicsView可以显示水平和垂直滚动条,以便浏览超出视口大小的场景内容。
- 抗锯齿和优化:QGraphicsView支持OpenGL加速和抗锯齿,以提高渲染质量和性能。
高级特性
视图变换和坐标系统
- 视图变换:QGraphicsView支持通过QTransform类进行复杂的仿射变换,包括平移、缩放、旋转和倾斜。这些变换可以通过setTransform()方法应用到视图上。
- 坐标系统:QGraphicsView维护了两个坐标系统:一个是视口的坐标系统,另一个是场景的坐标系统。这两个坐标系统之间可以通过mapToScene()和mapFromScene()方法进行转换。
交互和事件处理
- 交互模式:QGraphicsView可以通过setDragMode()方法设置不同的交互模式,例如NoDrag(无拖动)、ScrollHandDrag(手型拖动)和RubberBandDrag(橡皮筋拖动)。
- 事件处理:QGraphicsView可以处理各种事件,如鼠标事件、键盘事件和滚轮事件。可以通过重写QGraphicsView的事件处理函数来自定义这些行为。
渲染和优化
- 渲染提示:QGraphicsView可以通过setRenderHint()方法设置渲染提示,例如开启抗锯齿(QPainter::Antialiasing)和开启OpenGL加速(QPainter::OpenGL)。
- 视口更新模式:QGraphicsView可以通过setViewportUpdateMode()方法设置视口的更新模式,以优化渲染性能。可选的模式包括FullViewportUpdate(全视口更新)、MinimalViewportUpdate(最小视口更新)和SmartViewportUpdate(智能视口更新)。
自定义视口
- 视口类型:QGraphicsView的视口可以是任何类型的QWidget,包括QGLWidget,这使得可以在视口中使用OpenGL进行渲染。
- 视口事件:可以通过重写QGraphicsView的viewportEvent()函数来处理视口级别的事件,例如触摸事件和多点触控事件。
QGraphicsView类提供了许多常用的函数、信号和槽,用于管理和操作图形视图。以下是一些常用的函数及其说明:
常用函数
函数 | 描述 |
QGraphicsScene *scene() const | 返回与视图关联的场景。 |
void setScene(QGraphicsScene *scene) | 设置与视图关联的场景。 |
void setRenderHint(QPainter::RenderHint hint, bool enabled = true) | 设置渲染提示,如抗锯齿。 |
void setDragMode(QGraphicsView::DragMode mode) | 设置拖动模式,如平移或缩放。 |
void centerOn(const QPointF &pos) | 将视图中心移动到指定位置。 |
void scale(qreal sx, qreal sy) | 缩放视图。 |
void rotate(qreal angle) | 旋转视图。 |
void translate(qreal dx, qreal dy) | 平移视图。 |
QTransform transform() const | 返回视图的变换矩阵。 |
void setViewportUpdateMode(QGraphicsView::ViewportUpdateMode mode) | 设置视口更新模式,以优化渲染性能。 |
void setBackgroundBrush(const QBrush &brush) | 设置视图的背景画刷。 |
void setViewport(QWidget *viewport) | 设置视图的视口部件。 |
void setMatrix(const QMatrix &matrix, bool combine = false) | 设置视图的变换矩阵。 |
void setTransform(const QTransform &transform, bool combine = false) | 设置视图的变换。 |
void setTransformationAnchor(QGraphicsView::TransformationAnchor anchor) | 设置变换锚点。 |
void setResizeAnchor(QGraphicsView::ResizeAnchor anchor) | 设置调整大小锚点。 |
void setOptimizationFlag(QGraphicsView::OptimizationFlags flag, bool enabled = true) | 设置优化标志。 |
void setRubberBandSelectionMode(Qt::ItemSelectionMode mode) | 设置橡皮筋选择模式。 |
void setInteractive(bool allowed) | 设置视图是否允许交互。 |
void setAlignment(Qt::Alignment alignment) | 设置对齐方式。 |
void setCacheMode(QGraphicsView::CacheMode mode) | 设置缓存模式。 |
枚举说明
1. 设置渲染提示:void setRenderHint(QPainter::RenderHint hint, bool enabled = true)
-
- QPainter::RenderHint hint:
-
-
- QPainter::Antialiasing:启用边缘的反锯齿绘制,使图形边缘看起来更平滑。
- QPainter::TextAntialiasing:启用文本的反锯齿绘制,使文本显示更清晰。
- QPainter::SmoothPixmapTransform:使用平滑的像素图变换算法(如双线性插值),而不是邻近插值算法,使图像缩放和变换时更平滑。
- QPainter::HighQualityAntialiasing:提供更高质量的反锯齿效果,但可能会降低性能。
- QPainter::NonCosmeticDefaultPen:指定非装饰性的默认画笔。
- QPainter::Qt4CompatiblePainting:启用与Qt 4兼容的绘制模式。
- QPainter::LosslessImageRendering:尝试无损渲染图像。
-
-
- bool enabled:这个参数指定了是否启用该渲染提示。如果设置为true,则启用该渲染提示;如果设置为false,则禁用该渲染提示。默认值为true。
2. 设置拖动模式:setDragMode(QGraphicsView::DragMode mode)
-
- QGraphicsView::NoDrag:在这种模式下,视图不会响应鼠标拖拽事件,即用户无法通过拖拽来移动视图或场景。
- QGraphicsView::ScrollHandDrag:在这种模式下,用户的鼠标光标会变成一个手形图标,用户可以通过拖拽来滚动视图的内容。这种模式适用于浏览大型场景或地图。
- QGraphicsView::RubberBandDrag:在这种模式下,用户可以通过拖拽来选择一个矩形区域,该区域内的所有图形项都会被选中。这种模式常用于图形编辑软件中进行区域选择。
3. 设置渲染模式: void setViewportUpdateMode(QGraphicsView::ViewportUpdateMode mode)
-
- QGraphicsView::MinimalViewportUpdate:在这种模式下,只有场景中实际发生变化的部分会被更新。这可以提高性能,特别是在处理大型场景时。(默认模式)
- QGraphicsView::FullViewportUpdate:在这种模式下,每当场景中的任何可见部分发生变化或重新曝光时,视图将更新整个视口。这可能会导致性能下降,尤其是在处理复杂场景时。
- QGraphicsView::SmartViewportUpdate:在这种模式下,视图会根据需要智能地决定是更新整个视口还是只更新变化的部分。这是一种折中的方案,旨在平衡性能和准确性。
- QGraphicsView::BoundingRectViewportUpdate: 将重绘视口中所有更改的边界矩形。此模式的优点是 QGraphicsView 只在一个区域中搜索更改,从而最大限度地减少了确定需要重绘的内容所花费的时间。缺点是未更改的区域也需要重绘。
- QGraphicsView::NoViewportUpdate:在场景更改时永远不会更新其视口;用户需要控制所有更新。此模式禁用 QGraphicsView 中所有(可能很慢)项目可见性测试,适用于需要固定帧速率或以其他方式从外部更新视口的场景。
4. 设置变换的描点:void setTransformationAnchor(QGraphicsView::TransformationAnchor anchor)
-
- QGraphicsView::NoAnchor:没有特定的锚点,变换操作不会影响场景的位置。
- QGraphicsView::AnchorUnderMouse:变换操作会以鼠标光标下的点为基准点进行。
- QGraphicsView::AnchorViewCenter:变换操作会以视图的中心点为基准点进行。
- QGraphicsView::AnchorUnderMouseCursor:与AnchorUnderMouse相同,变换操作会以鼠标光标下的点为基准点进行。
5. 设置调整大小锚点:void setResizeAnchor(QGraphicsView::ResizeAnchor anchor)
-
- QGraphicsView::NoAnchor:没有特定的锚点,调整视图大小时场景的位置不会受到影响。
- QGraphicsView::KeepAspectRatio:保持场景的宽高比,调整视图大小时场景会按照比例缩放。
- QGraphicsView::KeepAspectRatioByExpanding:保持场景的宽高比,如果需要的话,场景会被扩展以填充整个视图。
- QGraphicsView::AnchorViewCenter:场景的中心点固定在视图的中心,调整视图大小时场景会围绕中心点缩放。
6. 设置优化标志:void setOptimizationFlag(QGraphicsView::OptimizationFlags flag, bool enabled = true)
-
- QGraphicsView::OptimizationFlags flag:
-
-
- QGraphicsView::DontSavePainterState:禁用保存和恢复绘图器状态,这可能会提高性能,但可能会导致绘图错误。
- QGraphicsView::DontAdjustForAntialiasing:禁用针对反锯齿的调整,这可能会提高性能,但可能会影响视觉效果。
- QGraphicsView::IndirectPainting:启用间接绘制,这可以减少绘图调用,但可能会增加内存使用。
- QGraphicsView::DontClipPainter:禁用绘图器的裁剪,这可能会提高性能,但可能会导致绘图超出预期区域。
-
-
- bool enabled:这个参数指定了是否启用该优化标志。如果设置为true,则启用该优化标志;如果设置为false,则禁用该优化标志。默认值为true。
7. 设置橡皮筋模式(框选效果):void setRubberBandSelectionMode(Qt::ItemSelectionMode mode)
-
- Qt::ContainsItemShape:只有完全包含在橡皮筋内的项目会被选中。
- Qt::IntersectsItemShape:与橡皮筋相交的项目会被选中。
- Qt::ContainsItemBoundingRect:只有完全包含在橡皮筋内的项目的边界矩形会被选中。
- Qt::IntersectsItemBoundingRect:与橡皮筋相交的项目的边界矩形会被选中。
7.1. 注意事项
-
-
- 橡皮筋选择模式的选择应根据应用程序的需求来确定。例如,如果希望只有完全包含在橡皮筋内的项目被选中,应选择ContainsItemShape。
- 橡皮筋选择模式仅在使用RubberBandDrag模式时有效。
-
8. 设置对其模式:void setAlignment(Qt::Alignment alignment)
函数用于设置视图中场景的背景对齐方式。这与在其他控件中设置文本或图像对齐的方式不同,因为它专门用于调整场景背景的画笔对齐
9. 设置缓存模式:void setCacheMode(QGraphicsView::CacheMode mode)
-
- QGraphicsView::NoCache:不使用缓存。
- QGraphicsView::CacheBackground:缓存背景,这可以提高滚动性能。
常用信号
信号 | 描述 |
void viewportEntered() | 当鼠标光标进入视口时发射。 |
void viewportExited() | 当鼠标光标离开视口时发射。 |
void scrollContentsBy(int dx, int dy) | 当视图内容滚动时发射。 |
void rubberBandChanged(QRubberBand::Shape newShape) | 当橡皮筋选择形状改变时发射。 |
常用槽
槽 | 描述 |
void updateScene(const QRectF &rect) | 更新场景的一部分。 |
void updateScene() | 更新整个场景。 |
void ensureVisible(const QRectF &rect, int xmargin = 50, int ymargin = 50, int timeout = 5000) | 确保指定的矩形区域在视图中可见。 |
void fitInView(const QRectF &rect, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio) | 调整视图以适应指定的矩形区域。 |
void centerOn(const QPointF &pos) | 将视图中心移动到指定位置。 |
这些函数、信号和槽提供了对QGraphicsView的全面控制,使得开发者能够创建丰富且交互性强的图形用户界面。
示例代码
以下是一个更高级的QGraphicsView使用示例,展示了如何自定义视口和处理视口事件:
class CustomViewport : public QWidget
{
protected:
void paintEvent(QPaintEvent *event) override
{
QPainter painter(this);
painter.fillRect(rect(), Qt::white);
// 自定义绘制代码...
}
};
QGraphicsScene *scene = new QGraphicsScene();
QGraphicsView *view = new QGraphicsView(scene);
CustomViewport *customViewport = new CustomViewport();
view->setViewport(customViewport);
// 自定义视口事件处理
view->viewport()->installEventFilter(this);
// 其他设置...
view->setWindowTitle("Advanced QGraphicsView Example");
view->setRenderHint(QPainter::Antialiasing);
view->setDragMode(QGraphicsView::ScrollHandDrag);
// 显示视图
view->show();
在这个示例中,我们创建了一个自定义的视口类CustomViewport,它继承自QWidget并重写了paintEvent()函数来实现自定义的绘制。然后,我们将这个自定义视口设置给了QGraphicsView。此外,我们还安装了事件过滤器来处理视口级别的事件。
通过这些高级特性和方法,QGraphicsView提供了极大的灵活性和强大的功能,使得开发者能够创建复杂的图形界面和交互式应用程序。