添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

图形视图框架提供了一个基于图形项的模型视图编程方法,主要由场景、视图和图形项三部分组成,这三部分分别由 QGraphicsScene、QGraphicsView和QGraphicsItem 这三个类来表示。
在这里插入图片描述

场景QGraphicsScene

QGraphicsScene类提供绘图场景(Scene)。场景是不可见的,是一个抽象的管理图形项的容器,可以向场景添加图形项,获取场景中的某个图形项等。

场景具有以下功能:

  • 提供用于管理大量图形项的高速接口函数
  • 传播事件到每个图形项spa
  • 管理图形项的状态,好比选择和处理焦点设计
  • 提供无变换的渲染功能,主要用于打印3d

一个场景分为3层: 图形项层(ItemLayer)、前景层(ForegroundLayer)、背景层(BackgroundLayer) 。场景的绘制老是从背景层开始,而后是图形项层,最后是前景层。前景层和背景层均可以使用QBrush进行填充,好比使用渐变和贴图等,也可以通过重新实现drawBackground()和drawForeground()函数来实现自定义的背景和前景。

可以通过**QGraphicsScene::addItem() 可以添加一个图元到场景中。图元可以通过多个函数进行检索。通过 QGraphicsScene::items()**和一些重载函数可以返回和点、矩形、多边形或向量路径相交的所有图元。**QGraphicsScene::itemAt()**返回指定点的最顶层图元。

QGraphicsScene scene;
QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100))
QTransform transform;;
QGraphicsItem *item = scene.itemAt(50, 50, transform);
// item == rect

QGraphicsScene的事件传播体系结构安排将场景事件传递到项目,并管理项目之间的传播。如果场景在某个位置接收到鼠标按下事件,则场景将事件传递到该位置的任何项目。

函数功能
void QGraphicsScene::addItem(QGraphicsItem *item) 添加子项目
void QGraphicsScene::removeItem(QGraphicsItem *item)移除子项目
QGraphicsLineItem *QGraphicsScene::addLine()添加直线项
QGraphicsEllipseItem *addEllipse()添加椭圆项
QGraphicsPathItem *QGraphicsScene::addPath(const QPainterPath &path, const QPen &pen = QPen(), const QBrush &brush = QBrush())添加路径项
QGraphicsPixmapItem *QGraphicsScene::addPixmap(const QPixmap &pixmap)添加图片项
QGraphicsRectItem *addRect()添加矩形项
QGraphicsTextItem *QGraphicsScene::addText(const QString &text, const QFont &font = QFont())添加文本项
QGraphicsPolygonItem *addPolygon(const QPolygonF &polygon, const QPen &pen = QPen(), const QBrush &brush = QBrush())添加多边形项
QGraphicsProxyWidget *QGraphicsScene::addWidget(QWidget *widget, Qt::WindowFlags wFlags = Qt::WindowFlags())添加装置项
QBrush backgroundBrush() const设置场景背景笔刷
void clearFocus()清除焦点
QList<QGraphicsItem *> collidingItems(const QGraphicsItem *item, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const获取与选定项目包含或相交的项
QGraphicsItemGroup *QGraphicsScene::createItemGroup(const QList<QGraphicsItem *> &items)将一些项添加到一个分组中,并返回该分组的指针
void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)拆除分组
void setFont(const QFont &font)设置字体 会触发 FontChange 信号
QBrush foregroundBrush() const获取前景笔刷
qreal height() const获取场景的高度
qreal width() const获取场景的宽度
bool isActive() const查看场景是否是活动的
QGraphicsItem *itemAt()返回位置为 QPoint 的项,如果有多项,则返回最上面那个项
QList<QGraphicsItem *> items(Qt::SortOrder order = Qt::DescendingOrder) const返回场景中的所有项
QList<QGraphicsItem *> items(const QPointF &pos, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape, Qt::SortOrder order = Qt::DescendingOrder, const QTransform &deviceTransform = QTransform()) const返回场景中的所有与该点相交的项
QList<QGraphicsItem *> items(const QRectF &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape, Qt::SortOrder order = Qt::DescendingOrder, const QTransform &deviceTransform = QTransform()) const返回有Rect包含或与Rect相交的所有项的列表、这些项按堆叠顺序排列(第一项是最上面的项)
QGraphicsItem *mouseGrabberItem() const返回场景中正在被鼠标抓取的项目(正在拖动的项目?)
void removeItem(QGraphicsItem *item)移除所有项目
void setSceneRect(const QRectF &rect)设置场景范围
bool QGraphicsScene::sendEvent(QGraphicsItem *item, QEvent *event) 事件过滤器

视图QGraphicsView

QGraphicsView提供了视图部件,它用来使场景中的内容可视化。
能够链接多个视图到同一个场景来为相同的数据集提供多个视口。视图部件是一个可滚动的区域,它提供了一个滚动条来浏览大的场景。
视图接收键盘和鼠标输入并转换为场景事件,并进行坐标转换后传送给可视场景。

QGraphicsScene scene;
myPopulateScene(&scene);
QGraphicsView view(&scene);
view.show();
函数功能
QGraphicsItem *itemAt(const QPoint &pos) const返回位置为 QPoint 的项,如果有多项,则返回最上面那个项
QList <QGraphicsItem *> items() const返回关联场景中的所有项
void setGraphicsEffect(QGraphicsEffect *effect)设置图形效果
QList<QGraphicsItem *> items(const QRect &rect, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const返回有Rect包含或与Rect相交的所有项的列表、这些项按堆叠顺序排列(第一项是最上面的项)
QList<QGraphicsItem *> items(int x, int y, int w, int h, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const返回有Rect包含或与Rect相交的所有项的列表、这些项按堆叠顺序排列(第一项是最上面的项)
QGraphicsScene *scene() const返回当前视图中的场景,如过没有,返回nullptr
void setSceneRect(const QRectF &rect)设置场景的可视化区域 (超出的部分,会出现滚动条)
void setSceneRect(qreal x, qreal y, qreal w, qreal h)设置场景的可视化区域 (超出的部分,会出现滚动条)
void setAlignment(Qt::Alignment alignment)设置场景在视图中的对齐方式,默认为居中对齐
QBrush backgroundBrush() const获取视图中的场景背景笔刷
void setBackgroundBrush(const QBrush &brush)设置视图中的场景背景笔刷
void setDragMode(QGraphicsView::DragMode mode)设置场景可否被鼠标左键拖动,默认无法被拖动
void setForegroundBrush(const QBrush &brush)设置前景笔刷
bool isInteractive() const是否运行场景交互(响应鼠标事件)
void setScene(QGraphicsScene *scene)设置场景
void setInteractive(bool allowed)设置运行场景交互(响应鼠标事件)
QBrush foregroundBrush() const获取前景笔刷

图形项QGraphicsItem

QGraphicsItem就是一些基本的图形元件,是所有图形项的基类。

  • QGraphicsEllipseItem 提供椭圆项
  • QGraphicsLineItem 提供直线项
  • QGraphicsPathItem 提供任意路径项
  • QGraphicsPixmapItem 提供pixmap项
  • QGraphicsPolygonItem 提供多边形项
  • QGraphicsRectItem 提供矩形项
  • QGraphicsSimpleTextItem 提供简单的文本标签项
  • QGraphicsTextItem 提供高级文本浏览器项
    在这里插入图片描述
    可以通过调用setVisible()来设置项是否应可见(即,绘制和接受事件)。隐藏项目也会隐藏其子项。同样,可以通过调用setEnabled()来启用或禁用项。如果禁用某个项目,它的所有子项也将被禁用。默认情况下,项目既可见又启用。若要切换是否选择项,请首先通过设置itemIsSelectable标志启用选择,然后调用setSelected()。通常,选择由场景切换,这是用户交互的结果。
class SimpleItem : public QGraphicsItem
  public:
      QRectF boundingRect() const override
          qreal penWidth = 1;
          return QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
                        20 + penWidth, 20 + penWidth);
      void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                 QWidget *widget) override
          painter->drawRoundedRect(-10, -10, 20, 20, 5, 5);

QGraphicsItem还支持以下功能:

  • 支持鼠标事件响应,包括鼠标按下、移动、释放和双击事件,以及鼠标悬停事件、滚轮事件和上下文菜单事件;
  • 键盘输入焦点和按键事件;
  • 支持拖放操作;
  • 分组,通过父子关系,通过QGraphicsItemGroup;
  • 碰撞检测

碰撞检测有两种方式:

  • 重载shape()返回项的准确形状,并依赖collapsWithItem()的默认实现来进行形状交集。如果形状复杂的话,这可能会很贵(指性能消耗)。
  • 重载collistWithItem()提供自己的自定义项和形状冲突算法。

可以调用contains()函数来确定项是否包含点。此函数也可以由项重新实现。contains()的默认行为基于调用shape()。

主要函数功能说明

分组函数功能
属性设置void setFlags(QGraphicsItem::GraphicsItemFlags flags)设置图形项的操作属性,例如,可选择,可移动等
void setOpacity(qreal opacity)设置透明度
void setGraphicsEffect(QGraphicsEffect *effect)设置图形效果
void setSelected(bool selected)图形项是否被选中
void setData(int key, const QVariant &value)用户自定义数据
坐标void setX(qreal x)图形项的X坐标
void setY(qreal y)图形项的Y坐标
void setZValue(qreal z)图形项的Z值,Z值控制图形项的叠放次序
void setPos(const QPointF &pos)图形项在父项中的位置
void setPos(qreal x, qreal y)图形项在父项中的位置
QPointF scenePos() const返回图形项在场景中的坐标,相当于调用mapToScene(0, 0)
坐标变化void resetTransform()复位坐标系,取消所有坐标变换
void setRotation(qreal angle)旋转一定角度,参数为正数时表示顺时针旋转
void setScale(qreal factor)按比例缩放,缺省值为1
坐标映射QPointF mapFromItem()将另一个图形项的一个点映射到本图形项的坐标系
QPointF mapFromParent()将父项的一个点映射到本图形项的坐标系
QPointF mapFromScene()将场景中的一个点映射到本图形项的坐标系
QPointF mapToItem()将本图形项内的一个点映射到另一个图形项的坐标系
QPointF mapToParent()将本图形项内的一个点映射到父项坐标系
QPointF mapToScene()将本图形项内的一个点映射到场景坐标系

参考:https://blog.csdn.net/kenfan1647/article/details/116991074

QGraphicsView有三个有效的坐标系,图形坐标,场景坐标,视图坐标。场景坐标等价于QPainter的逻辑坐标,一般以场景的中心为原点;视图坐标与设备坐标相同,是物理坐标,缺省以左上角为原点;图形项坐标是局部逻辑坐标,一般以图件的中心为原点。

图形项坐标

图形项使用自己的局部坐标(Item Coordinates),通常以其中心为(0,0),也是各种坐标变换的中心。图形项的鼠标事件的坐标是用局部坐标表示的,创建自定义图形项,绘制图形项时只需要考虑其局部坐标,QGaphicsScene和QGraphicsView会自动进行坐标转换。
在这里插入图片描述

一个图形项的位置是其中心点在父坐标系统中的坐标,对于没有父图形项的图形项,其父对象就是场景,图形项的位置就是在场景中的坐标。如果一个图形项的位置还是其他图形项的父项,父项进行坐标变化时,子项也做同样的坐标变换。

视图坐标(view Coordinates)就是窗口界面的物理坐标,单位是像素。视图坐标只与widget或视口有关,而与观察的场景无关。QGraphicsView视口的左上角坐标总是(0,0)。
在这里插入图片描述

所有的鼠标事件,拖放事件的坐标是由视图坐标定义的,然后用户需要讲这些坐标映射为场景坐标,以便和图形交互。

场景是所有图形项的基础坐标,场景坐标描述了每个顶层图形项的位置创建场景时可以定义场景矩形区的坐标范围,例如:
scene=new QGraphicsScene(-400,-300,800,600);这样定义的scene是左上角坐标为(-400,-300),宽度为800,高度为600的矩形区域,单位是像素。
在这里插入图片描述

每个图形项在场景里都有一个位置坐标,由函数QGraphicsItem::scenePos()给出;还有一个图形项边界矩形,由QGraphicsItem::sceneBoundingRect()函数给出。边界矩形可以使QGraphicsScene::changed()信号,参数是一个场景的矩形列表,表示发生变化的矩形区。

在场景中操作图形项时,进行场景到图形项,图形项到图形项,或视图到场景之间的坐标变换是比较有用的,即坐标映射(Coordinate Mapping).例如,在QGraphicsView的视口上单击鼠标时,通过函数QGraphicsView::mapToScene()可以将视图坐标映射为场景坐标,然后用QGraphicsScene::itemAt()函数可以获取场景中鼠标光标处的图形项。

事件处理与传播

图形视图框架中的事件都是先由视图进行接收,而后传递给场景,再由场景传递给相应的图形项。而对于键盘事件,它会传递给得到焦点的图形项,可使用QGraphicsScene类的setFocusItem()函数或者图形项自身调用setFocus()函数来设置焦点图形项。默认的,若是场景没有得到焦点,那么全部的键盘事件都会被丢弃。场景中的图形项得到了焦点,场景也会自动得到焦点。

对于鼠标悬停效果,QGraphicsScene会发送悬停事件。如果一个项接受悬停事件(请参见QGraphicsItem::acceptHoverEvents()),则当鼠标进入其区域时,它将收到一个QGaphicsSceneHoverCenter事件。当鼠标继续在项目区域内移动时,QGraphicsScene将向其发送GraphicsSceneHoverMove事件。当鼠标离开项目区域时,项目将收到一个GraphicsSceneHoverLeave事件。

  • contextMenuEvent()处理上下文菜单事件。
  • focusInEvent()和focusOutEvent()处理焦点进入和退出事件。
  • hoverEnterEvent()、hoverMoveEvent()和hoverLeaveEvent()处理hoverEnter、move和leave事件。
  • inputMethodEvent()处理输入事件,以获得辅助功能支持,如中文输入法获取输入内容。
  • keyPressEvent()和keyReleaseEvent()处理按键和释放事件。
  • mousePressEvent()、mouseMoveEvent()、mouseReleaseEvent()和 mouseDoubleClickEvent()处理鼠标按下、移动、释放、单击和双击事件。

示例:
main.cpp

#include <QApplication>
#include "myitem.h"
#include "myview.h"
#include <QTime>
int main(int argc, char* argv[ ])
    QApplication app(argc, argv);
    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
    QGraphicsScene scene;
    scene.setSceneRect(-200, -150, 400, 300);
    for (int i = 0; i < 5; ++i) {
        MyItem *item = new MyItem;
        item->setColor(QColor(qrand() % 256, qrand() % 256, qrand() % 256));
        item->setPos(i * 50 - 90, -50);
        scene.addItem(item);
    MyView view;
    view.setScene(&scene);
    view.setBackgroundBrush(QPixmap("../myView/background.png"));
    view.show();
    return app.exec();

myitem.h

#include <QGraphicsItem>
class MyItem : public QGraphicsItem
public:
    MyItem();
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
               QWidget *widget);
    void setColor(const QColor &color) { brushColor = color; }
private:
    QColor brushColor;
protected:
    void keyPressEvent(QKeyEvent *event);
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
    void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);

myitem.cpp

#include "myitem.h"
#include <QPainter>
#include <QCursor>
#include <QKeyEvent>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneContextMenuEvent>
#include <QMenu>
MyItem::MyItem()
    brushColor = Qt::red;
    setFlag(QGraphicsItem::ItemIsFocusable);
    setFlag(QGraphicsItem::ItemIsMovable);
    setAcceptHoverEvents(true);
QRectF MyItem::boundingRect() const
    qreal adjust = 0.5;
    return QRectF(-10 - adjust, -10 - adjust,
                  20 + adjust, 20 + adjust);
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
                   QWidget *)
    if (hasFocus()) {
        painter->setPen(QPen(QColor(255, 255, 255, 200)));
    } else {
        painter->setPen(QPen(QColor(100, 100, 100, 100)));
    painter->setBrush(brushColor);
    painter->drawRect(-10, -10, 20, 20);
// 鼠标按下事件处理函数,设置被点击的图形项得到焦点,并改变光标外观
void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *)
    setFocus();
    setCursor(Qt::ClosedHandCursor); //设置光标为手握下的形状
// 键盘按下事件处理函数,判断是不是向下方向键,若是是,则向下移动图形项
void MyItem::keyPressEvent(QKeyEvent *event)
    if (event->key() == Qt::Key_Down)
        moveBy(0, 10);
// 悬停事件处理函数,设置光标外观和提示
void MyItem::hoverEnterEvent(QGraphicsSceneHoverEvent *)
    setCursor(Qt::OpenHandCursor); //设置光标为手张开的形状
    setToolTip("I am item");
// 右键菜单事件处理函数,为图形项添加一个右键菜单
void MyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
    QMenu menu;
    QAction *moveAction = menu.addAction("move back");
    QAction *selectedAction = menu.exec(event->screenPos());
    if (selectedAction == moveAction) {
        setPos(0, 0);

myview.h

#include <QGraphicsView>
class MyView : public QGraphicsView
    Q_OBJECT
public:
    explicit MyView(QWidget *parent = 0);
protected:
    void keyPressEvent(QKeyEvent *event);

myview.cpp

#include "myview.h"
#include <QKeyEvent>
MyView::MyView(QWidget *parent) :
    QGraphicsView(parent)
void MyView::keyPressEvent(QKeyEvent *event)
    switch (event->key())
    case Qt::Key_Plus :
        scale(1.2, 1.2);
        break;
    case Qt::Key_Minus :
        scale(1 / 1.2, 1 / 1.2);
        break;
    case Qt::Key_Right :
        rotate(30);
        break;
    QGraphicsView::keyPressEvent(event);//必定要加上这个,不然在场景和图形项中就没法再接收到该事件了
                                    该类充当 QGraphicsItems 的容器。它与 QGraphicsView 一起使用,用于在 2D 表面上可视化图形项目,例如线条、矩形、文本甚至自定义项目。创建一个椭圆项添加到项目中返回QGraphicsEllipseItem*添加项目,使用QGraphicsItem*添加创建一个线段项添加到项目中返回QGraphicsLineItem*创建一个路径项添加到项目中返回QGraphicsPathItem*创建一个图片项添加到项目中返回QGraphicsPixmapItem*创建一个多边形项添加到项目中
                                    这两天做程序的时候碰到的问题,两个QGraphicsItem和一个QGraphicsPixmapItem放到一个场景中QGraphicsPixmapItem作为背景,两个普通item为两个小方块,其中一个可以移动 我要的效果是当那个可以移动的方块与另一个方块碰撞时 可以检测出来然后输出。QGraphicsItem::toolTip()会将给Item设置的提示以QString类型返回出来,这样就可以在程序中通过得到的item的指针来获取其提示信息,然后就能够进行判断 发生碰撞的是否是自己希望碰撞的。
                                    文章目录详述事件处理和传播公共类型enum ItemIndexMethodenum SceneLayer属性backgroundBrush: QBrushbspTreeDepth: intfocusOnTouch: boolfont: QFontforegroundBrush: QBrushitemIndexMethod: ItemIndexMethodminimumRenderSize: qrealpalette: QPalette**sceneRect**: QRectFstickyFocus: boo
                                    文章目录1. 平移2. 改变尺寸3. 旋转
我们在使用QGraphicsView框架的时候,经常需要自定义QGraphicsItem,并且需要实现Item的平移、改变大小和旋转的效果。接下来介绍他们的一种实现方式
1. 平移
平移效果如下图所示:
实现方式有两种方法:
使用QGraphicsItem本身的移动标志实现。
this->setFlag(QGraphicsItem::Ite...
3、场景的最大优势之一就是其快速有效地定位图形项的能力。即使场景中有数百万个图形项。
4、场景的另一个职责是传播来自视图的事件。要将事件发送到场景,可以构造一个继承QEvent的事件,然后使用QApplication::sendEvent()将其发送。event()负责将事件调度到各个图形项。
二、类型成员
1、QGra
                                     Graphics View提供了一个界面,它既可以管理大数量的定制2D graphical items,又可与它们交互,有一个view widget可以把这些项绘制出来,并支持旋转与缩放。这个柜架也包含一个事件传播结构,对于在scene中的这些items,它具有双精度的交互能力。Items能处理键盘事件,鼠标的按,移动、释放、双击事件,也可以跟踪鼠标移动。GraphicsView使用
1 QGraphicsScene scene;//场景
2 scene.addText("Hello, world!");//添加文本图形项
3 QGraphicsView view(&scene);//设
                                    QGraphicsScene简介
QGraphicsScene是图形视图框架的组成部分。它提供了一个用于管理大量2D图元的表面(Surface)。QGraphicsScene作为QGraphicsItem的容器,与QGraphicsView一起使用,以可视化2D曲面上的图元,例如线条、矩形、文本以及自定义图元。
QGraphicsScene还提供函数来有效确定图元的位置以及确定场景中任意区域内可见的图元。使用QGraphicsView部件,就可以可视化整个场景,或者放大并只查看场景中的某一部分。例如:
Header: #include < QGraphicsItem >
qmake: QT += widgets
Inherited By: QAbstractGraphicsShapeItem, QGraphicsItemGroup, QGraphicsLineItem, QGraphicsObject, and QGraphicsPixmapItem;
//此枚举描述QGraphicsItem的缓存模式。缓存通过分配和渲染到屏幕外像素缓冲区来加速渲.
                                    QGraphicsScene *scene = new QGraphicsScene;
    scene->setSceneRect(QRectF(0,0,400,400));
    ui->graphicsView->setScene(scene);    
setSceneRect(qreal x, qreal y, qreal w, qreal h)
x,y 是指的ui->graphicsView 的左上角这个点,
在QGraphicsScene中的坐标值,相当...
QGraphicsScene是管理QGraphicsItem的容器,它继承自QObject,而不是QWidget,因此它本身不可见,需要和QGraphicsView配合使用才能看到管理的项目。
2、常用接口
addItem:添加一个项,如果该项在其他场景中,将会先从旧的场景中删除,再添加到该场景中;
removeItem:删除一个项;
下面的接口用于创建特定的项并添加到场景中
addEllipse:椭圆
addLine:直线
addPath:绘制路径,绘制路径是由许多图形构建块组成的对象,如矩形、