1. 概述
简单来说,整个是面向对象的设计思路,涉及到三个类:QGraphicsItem
是具体的图形项;QGraphicsScene
是数据层,负责管理图形项QGraphicsItem
;QGraphicsView
是表现层,负责图形的渲染和用户交互,允许从不同角度或以不同方式查看同一QGraphicsScene
。
这种设计实现了数据(场景中的图形项)与视图(如何显示这些图形项)的分离,提高了代码的可维护性和复用性。
-
绘图场景 (QGraphicsScene):
- 作为图形项的容器,用于管理和存储所有的图形元素。
- 场景本身不可见,但提供了添加、删除、查找图形项的功能。
- 支持大规模数据集的高效管理,可管理数万个以上的item。
-
视图组件 (QGraphicsView):
- 负责将绘图场景中的内容渲染到屏幕上。
- 单个场景可以关联多个视图,允许从不同角度或以不同方式查看同一数据集。
- 提供了滚动条、缩放、平移等功能来增强用户界面的交互性。
-
图形项 (QGraphicsItem):
- 是所有图形元素的基础类,用于定义场景中的具体图形对象。
- 支持丰富的事件处理机制,包括但不限于鼠标点击、拖动、键盘输入等,使图形能够响应用户的操作。
- 开发者可以根据需要继承此基类,创建自定义的图形项以满足特定的应用需求。
2. 三者具体关系
事件传递路径:QGraphicsView
-> QGraphicsScene
-> QGraphicsItem
用户在视图中的交互(如点击、拖动)会转化为事件,这些事件首先由 QGraphicsView
接收,然后传递给 QGraphicsScene
,最终由对应的 QGraphicsItem
处理。
2.1 QGraphicsScene
- 作用: 作为图形项的容器,负责管理和存储所有的
QGraphicsItem
。 - 特点: 提供了添加、删除、查找图形项的方法,以及管理图形项的布局和层次关系。
- 示例代码:
QGraphicsScene *scene = new QGraphicsScene;
scene->addRect(QRectF(0, 0, 100, 100)); // scene添加item
2.2 QGraphicsView
- 作用: 作为
QGraphicsScene
的可视化窗口,负责将场景中的内容渲染到屏幕上。 - 特点: 提供了多种视图控制功能,如缩放、平移、滚动等。可以为同一个
QGraphicsScene
设置多个QGraphicsView
,以便从不同角度查看场景。 - 示例代码:
QGraphicsView *view = new QGraphicsView(scene); // 从一个view观察scene
view->show();
2.3 QGraphicsItem
- 作用: 作为场景中的基本图形单元,表示具体的图形元素(如矩形、椭圆、自定义形状等)。
- 特点: 支持各种事件处理,如鼠标事件、键盘事件、拖放事件等,使图形能够响应用户的操作。
- 示例代码:
QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 100, 100); // 具体的图元
scene->addItem(rect);
3. 简单案例
在这个示例中,MyRectItem
继承自 QGraphicsRectItem
,并重写了鼠标事件处理函数。当用户在 QGraphicsView
上操作时,事件会按照上述流程传递和处理。
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QMouseEvent>
#include <qdebug.h>
#include <QGraphicsSceneMouseEvent>
class MyRectItem : public QGraphicsRectItem {
public:
MyRectItem(qreal x, qreal y, qreal width, qreal height, QGraphicsItem *parent = nullptr)
: QGraphicsRectItem(x, y, width, height, parent) {}
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override {
// 处理鼠标按下事件
qDebug() << "Mouse pressed at" << event->scenePos();
QGraphicsRectItem::mousePressEvent(event);
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
// Graphics View基于笛卡尔坐标系。
// 场景内有一个矩形图元
QGraphicsScene *scene = new QGraphicsScene;
MyRectItem *rect = new MyRectItem(0, 0, 100, 200); //0,0是指定item在场景中的位置,在场景中(0,0)左上角。
scene->addItem(rect);
// 从一个视图内观察该场景
QGraphicsView *view1 = new QGraphicsView(scene);
view1->resize(400, 400);
view1->setRenderHint(QPainter::Antialiasing);
view1->setBackgroundBrush(Qt::red);
view1->show();
// 从另一个视图内观察该场景
QGraphicsView *view2 = new QGraphicsView(scene);
view2->resize(800, 800);
view2->setRenderHint(QPainter::Antialiasing);
view2->setBackgroundBrush(Qt::blue);
view2->show();
return app.exec();
}