【QT】GraphicsView框架入门篇

在Qt界面库中,对于需要绘制大量的、需要交互的图形,可使用Graphics View绘图架构,它是一种基于图形项(Graphics Item)的模型/视图模式,这种方式可以在一个场景中绘制大量图元项,且每个图元项都是可选择、可交互的。
GraphicsView 框架
在Graphics View绘图架构中,包括场景(Scene)、视图(View)、图形项(GraphicsItem)三部分。三部分用QGraphicsScene、QGraphicsView和QGraphicsItem三个类来表示。
(1)场景类:QGraphicsScene类
QGraphicsScene是一个放置图元的容器,是图形视图框架中的场景,拥有以下功能:
a、提供用于管理大量图形项(Items)的便捷接口。
b、分发事件给场景中的每一个图形项。
c、管理图形项(items)的状态,例如:选择和焦点处理等。
d、提供无变换的渲染功能,主要用于打印。
主要拥有以下方法:
场景是图形项QGraphicsItem对象的容器。调用QGraphicsScene::addItem()函数将图形项(Items)添加到场景中,然后调用众多的图形项查找函数来检索添加的图形项。
QGraphicsScene::items()函数和几个重载函数可以返回符合条件的所有图形项,这些图形项不是与指定的点、矩形、多边形或者矢量路径相交,就是包含在它们之中。
QGraphicsScene::itemAt()函数返回指定点的最上面的图形项(场景中的图形项可能会重叠)。所有的图形项寻找函数返回的图形项都是按照递减顺序进行的(例如第一个返回的图形项在最上面,最后返回的图形项在最下面)。
如果要从场景中删除一个图形项,可以使用QGraphicsScene::RemoveItem()函数。
场景允许通过QGraphicsScence::render()函数将场景的各个部分呈现到一个绘制设备中。
(2)视图类:QGraphicsView类
用于显示场景中的图元,QGraphicsView提供了视图widget,用来显示场景中的内容。可以将多个视图连接到同一个场景来为相同的数据集提供多个视口。
QGraphicsView是一个可滚动的区域控件,提供了一个滚动条来浏览大的场景,可以使用setDragMode()函数以QGraphicsView::ScrollHandDrag为参数来使光标变为手掌形状,从而可以拖动场景。如果设置setDragMode()的参数为QGraphicsView::RubberBandDrag,那么可以在视图上使用鼠标拖出橡皮筋框来选择图形项。
视图从键盘和鼠标接收输入事件,并将其转换成场景事件(在适当的地方将使用的坐标转换为场景坐标),然后将事件发送到可视化场景。使用QGraphicsView::transform(),视图可以转换场景的坐标系统。同样提供了转换视图和场景坐标的功能:QGraphicsView::mapToScene()和QGraphicsView::mapFromScene()。
默认的QGraphicsView提供了一个QWidget作为视口部件,如果要使用OpenGL进行渲染,可以调用QGraphicsView::setViewport()设置QGLWidget作为视口。QGraphicsView会获取视口部件的拥有权(ownership)。
(3)图元类:QGraphicsItem类
QGraphicsItem是场景中图形项的基类。图形视图框架为常见的典型形状提供了标准的图形项,例如:矩形(QGraphicsRectIem)、椭圆(QGraphicsEllipseItem)和文本项(QGraphicsTextItem)等。不过,只有当编写自定义图形项时才能发挥QGraphicsItem的强大功能。QGraphicsItem主要支持如下功能:
a、鼠标按下、移动、释放、双击、悬停、滚轮和右键菜单事件
b、键盘输入焦点和键盘事件
c、拖放事件
d、分组,使用QGraphicsItemGroup通过parent-child关系来实现
e、碰撞检测
除此之外,图形项还可以存储自定义的数据,可以使用setData()进行数据存储,然后使用data()获取其中的数据。
一个场景分为三层:图形项层(ItemLayer)、前景层(ForegroundLayer)和背景层(BackgroundLayer)。场景的绘制总是从背景层开始,然后是图形项层,最后是前景层。前景层和背景层都可以使用QBrush进行填充,比如使用渐变和贴图等。这里的前景色设置为了半透明的白色,当然也可以设置为其他的填充。
GraphicsView 坐标系
Graphics View基于笛卡尔坐标系。item在场景中的位置与几何形状通过x,y坐标来表示。当使用未经变形的视图来观察场景时,场景中的一个单位等于屏幕上的一个像素。在Graphics View绘图架构中涉及到了3个坐标系,即场景坐标、视图坐标及图形项坐标。
1.场景坐标:对应QPainter的逻辑坐标,以场景的中心为原点,X轴正方向向右,Y轴正方向向下;
【QT】GraphicsView框架入门篇_第1张图片
视图坐标:即窗口界面的物理坐标,单位是像素,其左上角为原点坐标,所有鼠标事件、拖拽事件最开始都使用视图坐标,为了和图元交互,需要转换坐标为场景坐标;
图形项坐标:图元存在于自己的本地坐标上,通常以图元的中心为原点,图元中心也是所有坐标变换的原点,图元坐标方向是X轴正方向向右,Y轴正方向向下(同上图)。
示例:

#include 
#include 
#include 
#include 
#include "math.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QGraphicsScene scene;   // 定义一个场景,设置背景色为红色
    scene.setBackgroundBrush(Qt::red);

    QPen pen;   // 定义一个画笔,设置画笔颜色和宽度
    pen.setColor(QColor(0, 160, 230));
    pen.setWidth(10);

    QGraphicsRectItem *m_rectItem = new QGraphicsRectItem();   // 定义一个矩形图元
    m_rectItem->setRect(0, 0, 80, 80);
    m_rectItem->setPen(pen);
    m_rectItem->setBrush(QBrush(QColor(255, 0, 255)));
    m_rectItem->setFlag(QGraphicsItem::ItemIsMovable);

    QGraphicsLineItem *m_lineItem = new QGraphicsLineItem();    // 定义一个直线图元
    m_lineItem->setLine(QLineF(0, 0, 100, 100));
    m_lineItem->setPen(pen);
    m_lineItem->setFlag(QGraphicsItem::ItemIsMovable);

    QGraphicsPathItem *m_pathItem = new QGraphicsPathItem();    // 定义一个路径图元
    QPainterPath path;
    path.moveTo(90, 50);
    for (int i = 1; i < 5; ++i) {
        path.lineTo(50 + 40 * cos(0.8 * i * M_PI), 50 + 40 * sin(0.8 * i * M_PI));
    }
    path.closeSubpath();
    m_pathItem->setPath(path);
    m_pathItem->setPen(pen);
    m_pathItem->setFlag(QGraphicsItem::ItemIsMovable);

    QGraphicsPolygonItem *m_polygonItem = new QGraphicsPolygonItem();   // 定义一个多边形图元
    QPolygonF polygon;
    polygon << QPointF(-100.0, -150.0) << QPointF(-120.0, 150.0)
            << QPointF(320.0, 160.0) << QPointF(220.0, -140.0);
    m_polygonItem->setPolygon(polygon);
    m_polygonItem->setPen(pen);
    m_polygonItem->setFlag(QGraphicsItem::ItemIsMovable);

    scene.addItem(m_rectItem);      // 把矩形图元添加到场景
    scene.addItem(m_lineItem);      // 把直线图元添加到场景
    scene.addItem(m_pathItem);      // 把路径图元添加到场景
    scene.addItem(m_polygonItem);   // 把多边形图元添加到场景

    QGraphicsView view(&scene); // 定义一个视图,并把场景添加到视图
    view.resize(1024, 768);
    view.show();

    return a.exec();
}

【QT】GraphicsView框架入门篇_第2张图片

你可能感兴趣的:(qt,ui,开发语言)