QGraphicsScene 类详解及常用方法
QGraphicsScene
是 PyQt5 中用于管理 2D 图形项(QGraphicsItem
) 的容器类,属于 Qt 图形视图框架(Graphics View Framework)的一部分。它提供高效管理大量图形项、事件处理、碰撞检测等功能,适用于复杂绘图、数据可视化、游戏开发等场景。以下是详细介绍及常用方法:
一、核心功能
- 图形项管理:添加、移除、查询图形项(如形状、文本、图像)。
- 坐标系统:支持场景坐标与视图坐标转换。
- 事件处理:响应鼠标、键盘、拖放事件。
- 渲染优化:自动裁剪不可见区域,提升性能。
- 碰撞检测:检测图形项之间的交互(如是否重叠)。
- 层次化结构:支持父子项关系(子项随父项移动/旋转)。
二、与相关类的关系
- **
QGraphicsView
**:用于显示QGraphicsScene
内容的视口(可多个视图显示同一场景)。 - **
QGraphicsItem
**:所有图形项的基类(如QGraphicsRectItem
、QGraphicsTextItem
)。 - **
QGraphicsEffect
**:为图形项添加视觉效果(如阴影、模糊)。
三、常用方法
1. 图形项管理
方法 | 说明 | 示例 |
---|---|---|
addItem(item: QGraphicsItem) | 添加图形项到场景 | scene.addItem(rect_item) |
removeItem(item: QGraphicsItem) | 移除图形项 | scene.removeItem(text_item) |
items() -> List[QGraphicsItem] | 获取所有图形项 | all_items = scene.items() |
items(x, y, width, height, order=Qt.DescendingOrder) -> List[QGraphicsItem] | 获取指定区域的图形项 | items = scene.items(0,0,100,100) |
clear() | 移除所有图形项 | scene.clear() |
2. 坐标与变换
方法 | 说明 | 示例 |
---|---|---|
setSceneRect(x, y, w, h) | 设置场景逻辑边界 | scene.setSceneRect(-100, -100, 200, 200) |
sceneRect() -> QRectF | 获取场景边界 | rect = scene.sceneRect() |
views() -> List[QGraphicsView] | 获取关联的所有视图 | view_list = scene.views() |
3. 事件处理
方法 | 说明 | 示例 |
---|---|---|
mousePressEvent(event) | 鼠标按下事件 | 重写以自定义交互 |
mouseMoveEvent(event) | 鼠标移动事件 | 重写实现拖拽功能 |
keyPressEvent(event) | 键盘按下事件 | 响应全局快捷键 |
4. 高级功能
方法 | 说明 |
---|---|
collidingItems(item, mode=Qt.IntersectsItemShape) -> List[QGraphicsItem] | 检测与指定项碰撞的其他项 |
focusItem() -> QGraphicsItem | 获取当前焦点项 |
setSelectionArea(path: QPainterPath, mode=Qt.IntersectsItemShape) | 通过路径选择区域内的项 |
四、代码示例
1. 基础场景搭建
python
from PyQt5.QtWidgets import QApplication, QGraphicsScene, QGraphicsView, QGraphicsRectItem
from PyQt5.QtCore import Qt, QRectF
# 创建场景和视图
scene = QGraphicsScene()
scene.setSceneRect(0, 0, 400, 300) # 设置场景范围
# 添加矩形项
rect_item = QGraphicsRectItem(50, 50, 100, 80)
rect_item.setBrush(Qt.blue)
scene.addItem(rect_item)
# 创建视图并显示
view = QGraphicsView(scene)
view.setWindowTitle("图形场景示例")
view.resize(600, 400)
view.show()
app = QApplication([])
app.exec_()
2. 处理鼠标点击事件
python
class CustomScene(QGraphicsScene):
def mousePressEvent(self, event):
# 在点击位置添加圆形
x, y = event.scenePos().x(), event.scenePos().y()
ellipse = QGraphicsEllipseItem(x-10, y-10, 20, 20)
ellipse.setBrush(Qt.red)
self.addItem(ellipse)
super().mousePressEvent(event)
# 使用自定义场景
scene = CustomScene()
view = QGraphicsView(scene)
3. 图形项选择与拖拽
python
# 允许项可移动、可选
rect_item.setFlag(QGraphicsItem.ItemIsMovable, True)
rect_item.setFlag(QGraphicsItem.ItemIsSelectable, True)
# 响应项选择变化
scene.selectionChanged.connect(lambda: print("选中项:", scene.selectedItems()))
五、性能优化技巧
- 启用 BSP 树索引:
python
scene.setItemIndexMethod(QGraphicsScene.BspTreeIndex) # 加速项查询
- 批量操作优化:
在大量增删项前,禁用视图刷新:python
view.setUpdatesEnabled(False) # 执行批量操作... view.setUpdatesEnabled(True)
- 简化项形状:
复杂图形项使用setCacheMode(QGraphicsItem.DeviceCoordinateCache)
缓存渲染结果。
六、应用场景
- 绘图工具:支持线条、形状的绘制与编辑。
- 数据可视化:动态显示图表节点与连线。
- 游戏开发:管理角色、障碍物、子弹等游戏元素。
- CAD 系统:处理工程图纸的层次化结构。
通过 QGraphicsScene
,可高效管理复杂图形交互,结合 QGraphicsView
和自定义图形项,实现高性能的 2D 图形应用!