The Graphics View Framework
Graphics 视图提供一个surface,用于大量2D 图形items 的管理和交互;还有一个 view widget 用于items 的可视化,并且支持缩放和旋转。
Framework 的事件传播机制,使得items 能够处理鼠标键盘事件,还可以跟踪鼠标轨迹。
Graphics View 利用BSP 树快速查找item,能够实时显示大场景,既使是在含有上百万items 情况下。
The Graphics View Architecture
Graphics View 是单场景多item
The Scene 场景
QGraphicsScene 作为Graphics View 的场景
提供一个快速接口用于管理大量items
给所有item 传播事件
管理item 的状态,如选中状态和获得焦点的状态
提拱untransformed 的渲染(主要是打印用)
scene 是QGraphicsItem 的容器。
将item 添加到场景: QGraphicsScene::addItem()
取回item :QGraphicsScene::items()
QGraphicsScene::itemAt() 返回一个特定点的top item
QGraphicsScene scene;
QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100));
QGraphicsItem *item = scene.itemAt(50, 50);
// item == rect
QGraphicsScene 的事件传播机制将场景的事件投递到各个item。如果QGraphicsScene 在一个特定的位置收到一个鼠标点击事件,QGraphicsScene 会将此事件传给处于这个位置的item。
在场景上选择items:QGraphicsScene::setSelectionArea(),参数是任意shape
获得当前选中的items: QGraphicsScene::selectedItems()
获得处于焦点状态的item:QGraphicsScene::focusItem()
设置item 的焦点状态:QGraphicsScene::setFocusItem() or QGraphicsItem::setFocus()
The View 视图
QGraphicsView 的 view widget将场景的内容可视化。你可以添加多个视图到一个场景中,对同一个数据集提供多种视觉呈现。
view widget 是一个滚动区域,对大场景以滚动进行导航。要支持OpenGL 调用QGraphicsView::setViewport(),传参数 QGLWidget。
QGraphicsScene scene;
myPopulateScene(&scene);
QGraphicsView view(&scene);
view.show();
视图将收到的鼠标键盘事件转成场景事件(相应的坐标转成场景坐标)
QGraphicsView::transform() 利用其转置矩阵转换场景坐标系统;以此支持缩放和旋转的高级变换。
在视图和场景之间进行坐标变换: QGraphicsView::mapToScene() ,QGraphicsView::mapFromScene()
The Item
经典形状标准item:QGraphicsRectItem,QGraphicsEllipseItem,QGraphicsTextItem
QGraphicsItem 拥有最强大的定制能力。
QGraphicsItem 的特性:
拖拽
分组(形成父子关系,使用QGraphicsItemGroup)
碰撞检测
item 可以包含其他的item
QGraphicsItem::contains(), QGraphicsItem::boundingRect(), QGraphicsItem::collidesWith() 工作在本地坐标下。
The Graphics View Coordinate System
三种坐标系统:Item 坐标, 场景坐标,视图坐标;Graphics View 有相应的函数在这三种坐标间转换。
Coordinate Mapping 坐标映射
QGraphicsView 的视口下点击鼠标,要想知道光标下的item 是什么可以先调用QGraphicsView::mapToScene(),接着调用QGraphicsScene::itemAt()
要知道一个item 在视口的位置,先调用QGraphicsItem::mapToScene(),然后 QGraphicsView::mapFromScene()
最后,视图的一个区域包含哪些item,以参数QPainterPath 调用QGraphicsView::mapToScene(),接着以“已映射”的路径为参数调用 QGraphicsScene::items()
QGraphicsItem::mapToParent()
QGraphicsItem::mapFromParent()
QGraphicsItem::mapToItem()
QGraphicsItem::mapFromItem().
Drag and Drop 拖拽
当视图收到drag,则将drag 和drop 转换成QGraphicsSceneDragDropEvent,场景又将事件传给相应的item。
void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
QMimeData *data = new QMimeData;
data->setColor(Qt::green);
QDrag *drag = new QDrag(event->widget());
drag->setMimeData(data);
drag->start();
}
要拦截场景的drag 和drop 事件,重写QGraphicsScene::dragEnterEvent() 函数。
为items 启用drag,drop 支持:QGraphicsItem::setAcceptDrops()。相关事件:QGraphicsItem::dragEnterEvent(), QGraphicsItem::dragMoveEvent(), QGraphicsItem::dragLeaveEvent(), 和QGraphicsItem::dropEvent()
请参考:SDK 附带的Drag and Drop Robot 示例程序。
Cursors and Tooltips 光标和提示信息
设置item 的光标和提示:QGraphicsItem::setCursor(),QGraphicsItem::setToolTip()
视图的光标:QGraphicsView::setCursor() // ? 4 view or item
Animation 动画
方法一、items 继承QGraphicsObject,并联合使用QPropertyAnimation
方法二、自定义item,继承QObject 和QGraphicsItem。给item 设置一个定时器,在QObject::timerEvent() 事件中控制动画。
方法三、调用 QGraphicsScene::advance(), 此函数转而调用QGraphicsItem::advance()