简述
图形视图(Graphics View)提供了一个平台,用于大量自定义2D图元的管理与交互,并提供了一个视图部件(view widget)来显示可以缩放和旋转的图元。
框架包括一个事件传播架构,支持场景(Scene)中的图元(Item)进行精确的双精度交互功能。图元可以处理键盘事件、鼠标按下、移动、释放和双击事件,同时也能跟踪鼠标移动。
图形视图使用一个BSP(Binary Space Partitioning - 二叉空间分割)树,以提供对图形元素的快速查找,正因为如此,它可以使超大的场景实时地可视化,即使包含数百万的图元。
图形视图架构
图形视图提供了一个基于图元的方式来实现模型视图(model-view)编程,很像InterView中的便利类:QTableView、QTreeView和QListView。多个视图可以观察一个单独的场景,场景则包含了不同的几何形状图元 。
场景
QGraphicsScene提供了图形视图场景。
场景有以下职责:
提供一个快速的接口,用于管理大量图元
向每个图元传递事件
管理图元的状态,如:选中、焦点处理
提供未进行坐标转换的渲染功能,主要用于打印
场景是QGraphicsItem对象的容器。调用QGraphicsScene::addItem()将图元添加到场景中后,你就可以通过调用场景中的不同的查找函数来查找其中的图元。QGraphicsScene::items()函数及其重载函数可以返回所有图元,包括:点、矩形、多边形、通用矢量路径。
视图
QGraphicsView提供了视图部件,将一个场景中的内容显示出来。你可以附加多个视图到同一个场景,从而针对同一数据集提供几个视口(viewport)。该视图部件是一个滚动区域(scroll area),为大型场景浏览提供滚动条。如果要启用OpenGL支持,可通过调用QGraphicsView::setViewport(),将一个QGLWidget设置为视口。
图元
QGraphicsItem是场景中图元的基类。图形视图提供了一些典型形状的标准图元,例如:矩形 ( QGraphicsRectItem )、椭圆 ( QGraphicsEllipseItem ) 、文本项 ( QGraphicsTextItem )。但当你自定义图元时,QGraphicsItem强大的特性就体现出来了。除此之外,QGraphicsItem还支持以下特性:
鼠标按下、移动、释放和双击事件,以及鼠标悬浮事件、滚轮事件和上下文菜单事件。
键盘输入焦点和键盘事件。
拖放。
分组:通过父子关系,或QGraphicsItemGroup。
碰撞检测。
和QGraphicsView一样,处于局部坐标系下的图元,也提供了很多函数用于图元和场景之间、图元到图元的坐标映射。此外,和QGraphicsView一样,它可以通过一个矩阵(matrix):QGraphicsItem::transform()来转换其自身的坐标系,这对于旋转和缩放单个图元非常有用。
代码结构
由于网上提供的方法,大多数操作Qt图形视图框架 显示的方式不够严谨,有为设计的初衷MVC。所以我按照企业级开发要求,重新封装了一套,以便日后自己使用。
图片中显示了模型代码的层级结构
下面是代码描述
Hgraphicdef.h
/****************************************************************************
** brief 用户交互图形视图模型中的变量, *枚举类型,*结构体,*类
** Write by LiHaiTao
****************************************************************************/
#ifndef HGRAPHICDEF_H
#define HGRAPHICDEF_H
#endif // HGRAPHICDEF_H
HGraphicsItem
/****************************************************************************
** brief 自定义Item
** Write by LiHaiTao
****************************************************************************/
#ifndef HGRAPHICITEM_H
#define HGRAPHICITEM_H
#include<QGraphicsItem>
#include<QGraphicsRectItem>
/**
* @brief The HGraphicsItem class 自定义ITem,需要扩展可以继承它
* @Write LiHaiTao
*/
class HGraphicsItem : public QGraphicsItem
{
public:
HGraphicsItem(QGraphicsItem *parent = 0);
~HGraphicsItem();
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR);
virtual QRectF boundingRect() const;
private:
};
/**
* @brief The HGraphicsRectItem class 重新扩展QGraphicsRectItem
* @Write LiHaiTao
*/
class HGraphicsRectItem : public QGraphicsRectItem
{
public:
HGraphicsRectItem(const QRectF &rect ,QGraphicsItem *parent = 0);
~HGraphicsRectItem();
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR);
private:
};
#endif // HGRAPHICITEM_H
HGraphicsScene
/****************************************************************************
** brief 自定义Scene
** Write by LiHaiTao
****************************************************************************/
#ifndef HGRAPHICSENCE_H
#define HGRAPHICSENCE_H
#include <QGraphicsScene>
#include "HGraphicsItem.h"
class HGraphicsScene : public QGraphicsScene
{
public:
HGraphicsScene(QObject *parent = 0);
~HGraphicsScene();
private:
HGraphicsItem* m_Item;
HGraphicsRectItem* m_RectItem;
};
#endif // HGRAPHICSENCE_H
HGraphicsView
/****************************************************************************
** brief 自定义View
** Write by LiHaiTao
****************************************************************************/
#ifndef HGRAPHICVIEW_H
#define HGRAPHICVIEW_H
#include<QGraphicsView>
#include "HGraphicsScene.h"
class HGraphicsView : public QGraphicsView
{
public:
HGraphicsView(QWidget *parent = 0);
~HGraphicsView();
private:
HGraphicsScene* m_Scene;
};
#endif // HGRAPHICVIEW_H
整个视图框架封装,只有通过操作View来显示。