精华内容
下载资源
问答
  • Qt图形视图框架详解

    2021-06-09 03:51:00
    介绍Qt中的Graphics View Framework,涉及View、Scene、Item的关系,如何自定义QGraphicsItem、处理Item之间的关联、如何布局及定义自己的布局Item、如何变幻Item、如何应用动画、如何处理拖放、如何给Item应用图形...
  • 详解介绍Qt中视图框架机制及场景中主要的常用函数作用及用法,是学习者可以对Qt的场景视图有深入的了解。
  • 一个C++语言编写的测试demo,Qt5.9可编译运行。可作为学习Qt图形视图显示,或SVG二次开发的初步了解
  • 74 QT图形视图框架(Graphics View)

    千次阅读 2019-05-11 23:07:57
    (1)Graphics View框架结构中,系统可以利用Qt绘图系统的反锯齿、OpenGL工具来改善绘图性能。 (2)Graphics View支持事件传播体系结构,可以使图元在场景(scene)中的交互能力提高1倍,图元能够处理键盘事件和...

    Graphics View简介================================

    Graphics View框架结构的主要特点如下。

    (1)Graphics View框架结构中,系统可以利用Qt绘图系统的反锯齿、OpenGL工具来改善绘图性能。

    (2)Graphics View支持事件传播体系结构,可以使图元在场景(scene)中的交互能力提高1倍,图元能够处理键盘事件和鼠标事件。其中,鼠标事件包括鼠标按下、移动、释放和双击,还可以跟踪鼠标的移动。

    (3)在Graphics View框架中,通过二元空间划分树(Binary Space Partitioning,BSP)提供快速的图元查找,这样就能够实时地显示包含上百万个图元的大场景。

    Graphics View的三元素=============================

    • 场景类:QGraphicsScene类
    • 视图类:QGraphicsView类
    • 图元类:QGraphicsItem类

    1.场景类:QGraphicsScene类

    场景类主要完成的工作包括提供对它包含的图元的操作接口和传递事件、管理各个图元的状态(如选择和焦点处理)、提供无变换的绘制功能(如打印)等。

    事件传播体系结构将场景事件发送给图元,同时也管理图元之间的事件传播。如果场景接收到了在某一点的鼠标单击事件,场景会将事件传给这一点的图元。

    管理各个图元的状态(如选择和焦点处理)。可以通过QGraphicsScene:: setSelectionArea()函数选择图元,选择区域可以是任意的形状,使用QPainterPath表示。若要得到当前选择的图元列表,则可以使用函数QGraphicsScene:: selectedItems()。可以通过QGraphicsScene:: setFocusItem()函数或QGraphicsScene:: setFocus()函数来设置图元的焦点,获得当前具有焦点的图元使用函数QGraphicsScene::focusItem()。

    2.视图类:QGraphicsView类

    QGraphicsView是可滚动的窗口部件,可以提供滚动条来浏览大的场景。如果需要使用OpenGL,则可以使用QGraphicsView::setViewport()将视图设置为QGLWidget。

    视图接收键盘和鼠标的输入事件,并将它们翻译为场景事件(将坐标转换为场景的坐标)。使用变换矩阵函数QGraphicsView::matrix()可以变换场景的坐标,实现场景缩放和旋转。QGraphicsView提供QGraphicsView::mapToScene()和QGraphicsView:: mapFromScene()用于与场景的坐标进行转换。

    3.图元类:QGraphicsItem类

    它是场景中各个图元的基类,在它的基础上可以继承出各种图元类,Qt已经预置的包括直线(QGraphicsLineItem)、椭圆(QGraphicsEllipseItem)、文本图元(QGraphicsTextItem)、矩形(QGraphicsRectItem)等。

    QGraphicsItem主要有以下功能。

    • 处理鼠标按下、移动、释放、双击、悬停、滚轮和右键菜单事件。
    • 处理键盘输入事件。
    • 处理拖曳事件。
    • 分组。
    • 碰撞检测。

    GraphicsView的坐标系统

    1.场景坐标

    场景坐标是所有图元的基础坐标系统。场景坐标系统描述了顶层的图元,每个图元都有场景坐标和相应的包容框。场景坐标的原点在场景中心,坐标原点是x轴正方向向右,y轴正方向向下。

    QGraphicsScene类的坐标系以中心为原点(0,0),如图所示。

    2.视图坐标

    视图坐标是窗口部件的坐标。视图坐标的单位是像素。

    QGraphicsView视图的左上角是(0,0),x轴正方向向右,y轴正方向向下。所有的鼠标事件最开始都是使用视图坐标。 QGraphicsView类继承自QWidget类,因此它与其他的QWidget类一样,以窗口的左上角作为自己坐标系的原点,如图所示。

    3.图元坐标

    图元使用自己的本地坐标,这个坐标系统通常以图元中心为原点,这也是所有变换的原点。图元坐标方向是x轴正方向向右,y轴正方向向下。创建图元后,只需注意图元坐标就可以了,QGraphicsScene和QGraphicsView会完成所有的变换。

    QGraphicsItem类的坐标系,若在调用QGraphicsItem类的paint()函数重绘图元时,则以此坐标系为基准,如图7.4所示。

    Graphics View框架提供了多种坐标变换函数。

    映 射 函 数

    转 换 类 型

    QGraphicsView::mapToScene()

    视图到场景

    QGraphicsView::mapFromScene()

    场景到视图

    QGraphicsItem:: mapFromScene()

    场景到图元

    QGraphicsItem:: mapToScene()

    图元到场景

    QGraphicsItem:: mapToParent()

    子图元到父图元

    QGraphicsItem:: mapFromParent()

    父图元到子图元

    QGraphicsItem:: mapToItem()

    本图元到其他图元

    QGraphicsItem:: mapFromItem()

    其他图元到本图元

     

     

     

     

     

     

     

    实例代码:

    链接:https://pan.baidu.com/s/1o59uuB2UmkKSiNT3QrHg5Q 
    提取码:4fj9 

     

    参考:

    《快速掌握PyQt5》第三十四章 图形视图框架:https://blog.csdn.net/La_vie_est_belle/article/details/86999825

    Qt 之图形视图框架:https://blog.csdn.net/liang19890820/article/details/51966791

    Qt 图形视图框架 (一):https://blog.csdn.net/qq_25800311/article/details/81002822

    Qt 图形视图框架(二):https://blog.csdn.net/qq_25800311/article/details/81015815

    Qt图形视图框架基本图元:https://baijiahao.baidu.com/s?id=1620839120064482087&wfr=spider&for=pc

    Qt之图形视图框架:http://www.sgyma.com/hhlm_49365.html

    【Qt图形视图框架详解】 - 安晓辉 - 在线视频教程-CSDN学院

    Qt工作笔记-视图(QGraphicsView)的放大和缩小(通过滚轮):https://blog.csdn.net/qq78442761/article/details/81503006

     

    百度文库:

    Qt 5图形视图框架_百度文库

    QT图形视图框架(The Graphics View Framework)_图文_百度文库

    第7章 Qt 5图形视图框架

     

     

     

     

     

    展开全文
  • 一、描述 1、QGraphicsWidget 是一个扩展的基础项,它在 QGraphicsItem 之上提供额外的功能。 它在很多方面与 QWidget 相似: 提供调色板、字体、样式。 有geometry()。 可使用 setLayout() 和 layout()支持布局...

    一、描述

    1、QGraphicsWidget 是一个扩展的基础项,它在 QGraphicsItem 之上提供额外的功能。 它在很多方面与 QWidget 相似:

    • 提供调色板、字体、样式。
    • geometry()。
    • 可使用 setLayout() 和 layout()支持布局。
    • 支持使用grabShortcut() 和insertAction() 的快捷键和QAction
    • QGraphicsItem不同,QGraphicsWidget不是抽象类。

    2、由于QGraphicsWidget与QWidget类似并且具有相似的API,因此将小部件从QWidget移植到QGraphicsWidget比QGraphicsItem更为容易。

    3、QGraphicsWidget默认支持的Qt小部件属性如下:

    • Qt::WA_RightToLeft:表示窗口小部件的布局方向是从右到左。
    • Qt::WA_SetStyle:表示小部件具有自己的样式。如果设置了此属性(由setStyle()设置),则小部件已明确分配了样式。如果未设置,则小部件将使用场景或应用程序的样式。
    • Qt::WA_Resized:表示小部件具有明确的大小。
    • Qt::WA_SetPalette:表示小部件有自己的调色板。
    • Qt::WA_SetFont:表示小部件有自己的字体。
    • Qt::WA_WindowPropagation:使顶层窗口从其父级继承字体、调色板和区域设置。

    4、尽管QGraphicsWidget继承自QObjectQGraphicsItem(这俩都有一套自己的管理子项的系统),但是应该使用QGraphicsItem提供的功能(而不是QObject)来管理父项和子项之间的关系。由QGraphicsItem的函数控制图形项的堆叠顺序及其所有权。

    二、属性成员

    1、autoFillBackground : bool

    是否自动填充小部件背景。如果启用,此属性将导致 Qt 在调用paint() 方法之前填充小部件的背景。使用的颜色由小部件调色板中的 QPalette::Window 颜色角色定义。QGraphicsWidget总是用QPalette::Window 填充,除非设置了 WA_OpaquePaintEvent 属性(属性)。默认此属性为 false。

    2、focusPolicy : Qt::FocusPolicy

    接受键盘焦点的策略(焦点策略Qt::FocusPolicy)。

    如果小部件处理键盘事件,则必须为小部件启用键盘焦点例如,QLineEdit 构造函数调用 setFocusPolicy(Qt::StrongFocus)。

    如果您启用焦点策略(即,不是Qt::NoFocus),QGraphicsWidget 将自动启用 ItemIsFocusable 标志(图形项标志)。在小部件上设置 Qt::NoFocus 将清除 ItemIsFocusable 标志。

     3、font : QFont

    小部件的字体。此属性由显式定义的字体属性和从窗口小部件的父级隐式继承的属性组成。 因此,与使用 setFont()设置的字体相比,font()可以返回不同的字体。 此方案允许您在字体中定义单个条目,而不会影响字体的继承条目。

    当小部件的字体更改时,它会根据其父小部件解析其条目。 如果小部件没有父小部件,它会根据场景解析其条目。 然后小部件向自己发送一个FontChange()事件并通知它的所有后代,以便他们也可以解析他们的字体。默认情况下,此属性包含应用程序的默认字体。

    4、geometry : QRectF

    小部件的几何形状。将图形项的几何体设置为矩形。调用此函数会修改图形项的位置和大小。该图形项首先移动,然后调整大小。调用此函数的一个副作用是小部件将接收一个移动事件和一个调整大小事件。 此外,如果小部件分配了布局,则布局将激活。

    5、layout : QGraphicsLayout*

    小部件的布局。QGraphicsWidget 拥有布局的所有权。

    6、maximumSize : const QSizeF / minimumSize : const QSizeF / preferredSize : const QSizeF

    小部件的最大 / 最小 / 首选尺寸。

    7、palette : QPalette

    小部件的调色板。调色板为颜色组提供颜色和画笔,定义小部件及其子项的一般外观。QPalette 由显式定义的颜色组和从窗口小部件的父级隐式继承的组组成。 因此,palette() 可以返回与 setPalette() 设置不同的调色板。当小部件的调色板更改时,它会根据其父小部件解析其条目,或者如果它没有父小部件,则会针对场景进行解析。 然后它向自己发送一个 PaletteChange() 事件,并通知它的所有后代,以便他们也可以解析他们的调色板。默认情况下,此属性包含应用程序的默认调色板。

    8、size : QSizeF

    小部件的大小。此属性仅影响小部件的宽度和高度。小部件的位置和左上角不受影响。调整小部件的大小会触发GraphicsSceneResize() 事件。

    9、sizePolicy : QSizePolicy

    大小策略。

    10、windowFlags : Qt::WindowFlags

    窗口标志。窗口标志一个窗口类型(如 Qt::Dialog)和几个提供窗口行为提示的标志的组合。默认情况下,此属性不包含窗口标志。窗户是面板,如果设置了Qt::Window标志,则 ItemIsPanel图形项标志) 标志将自动设置。如果清除 Qt::Window 标志,则 ItemIsPanel 标志也会被清除。 注意,ItemIsPanel 标志可以独立于 Qt::Window 设置。

    11、windowTitle : QString

    窗口标题。此属性仅用于窗口。

    三、成员函数

    1、void addAction(QAction *action) / void addActions(QList<QAction *> actions)

    添加动作到QAction列表。QGraphicsWidgets 有一个 QActions 列表。

    2、void adjustSize()

    将小部件的大小调整为其有效的首选大小(effectiveSizeHint(Qt::PreferredSize)(QGraphicsLayoutItem))。当图形项第一次显示时,这个函数被隐式调用。

    3、bool close()

    关闭小部件。如果小部件成功关闭,则返回 true,否则返回false。首先向小部件发送一个 QCloseEvent,该小部件可能接受也可能不接受该事件。如果事件被忽略,则不做任何操作。如果事件被接受,它将关闭小部件。如果小部件设置了 Qt::WA_DeleteOnClose 属性,它将被删除。

    4、[虚函数] bool focusNextPrevChild(bool next)

    按下 Tab 和 Shift+Tab,查找一个新的小部件以将键盘焦点置于其上,如果可以找到新的小部件,则返回 true否则返回 false。如果 next 为true,则向前搜索否则向后搜索。

    5、QGraphicsWidget *focusWidget()

    如果此小部件、此小部件的子代或后代当前具有输入焦点,则此函数将返回指向该小部件的指针。

    6、[信号] void geometryChanged()

    只要在 setGeometry() 中更改几何图形,就会发出此信号。

    7、void getWindowFrameMargins(qreal *left, qreal *top, qreal *right, qreal *bottom)

    获取小部件的窗口边距。

    8、int grabShortcut(const QKeySequence &sequence, Qt::ShortcutContext context = Qt::WindowShortcut)

    向 Qt 的快捷系统添加一个快捷键(QKeySequence是封装了快捷键按键信息的类),该系统在给定的环境(参数2)中监视给定的键序列。

    Qt::ShortcutContext:快捷键所处的环境。

    • Qt::WidgetShortcut:当父小部件具有焦点时,快捷键处于活动状态。
    • Qt::WidgetWithChildrenShortcut:当父小部件或其任何子部件具有焦点时,快捷键处于活动状态。
    • Qt::WindowShortcut:对于不属于窗口的小部件(即顶级小部件及其子部件),快捷键适用于场景。
    • Qt::ApplicationShortcut:快捷键适用于整个应用程序。

    9、void initStyleOption(QStyleOption *option)

    根据样式设置对象(QStyleOption)设置QGraphicsWidget对象的小部件样式。QStyleOption对象有如下成员:

    默认会用这些成员设置QGraphicsWidget的以下属性:

    • state & QStyle::State_EnabledisEnabled()
    • state & QStyle::State_HasFocushasFocus()
    • state & QStyle::State_MouseOverisUnderMouse()
    • direction:layoutDirection()
    • rect:rect().toRect()
    • palette:palette()
    • fontMetrics:QFontMetrics(font())

    10、void insertAction(QAction *before, QAction *action) / void insertActions(QAction *before, QList<QAction *> actions)

    将参数2的动作插入到参数1的动作之前。如果before == nullptr或before不是当前小部件的动作则在动作列表后面追加。

    11、bool isActiveWindow()

    小部件的窗口位于活动窗口中,或者小部件没有窗口但位于活动场景(即当前具有焦点的场景)中,则返回 true。(活动窗口是包含当前具有输入焦点的子窗口小部件或本身具有输入焦点的窗口)

    12、[虚函数] void paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr)

    由场景调用,在本地坐标中为窗口绘制窗口边框。基本实现使用当前样式来呈现边框和标题栏。

    13、void removeAction(QAction *action)

    移除动作。

    14、void resize(qreal w, qreal h)

    重设宽高。

    15、void setAttribute(Qt::WidgetAttribute attribute, bool on = true)

    如果 on 为true,则此函数启用属性,否则属性被禁用。实用的属性

    16、void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)

    设置左、上、右、下的内容边距。布局使用内容边距来定义子小部件和布局的位置。

    17、void setLayout(QGraphicsLayout *layout)

    设置布局。在分配新布局之前,将删除任何现有布局管理器。QGraphicsWidget 拥有布局的所有权。

    18、[static] void setTabOrder(QGraphicsWidget * A, QGraphicsWidget * B)

    设置当按下tab键时焦点从A移到B。

    设置焦点a->b->c->d移动:

     setTabOrder(a, b); // a -> b
     setTabOrder(b, c); // a -> b -> c
     setTabOrder(c, d); // a -> b -> c -> d

    19、void setWindowFrameMargins(QMarginsF margins)

    设置小部件窗口边距。默认边距由样式提供,取决于当前窗口标志。如果您想绘制自己的窗口样式,可以设置自己的框架边距以覆盖默认边距。

    20、bool testAttribute(Qt::WidgetAttribute attribute)

    返回小部件是否启用了属性。

    21、void unsetWindowFrameMargins()

    将边框边距重置为样式提供的默认值。

    四、事件成员函数

    1、void changeEvent(QEvent *event)

    状态更改事件。包括:

    • QEvent::ActivationChange
    • QEvent::EnabledChange
    • QEvent::FontChange
    • QEvent::StyleChange
    • QEvent::PaletteChange
    • QEvent::ParentChange
    • QEvent::LayoutDirectionChange
    • QEvent::ContentsRectChange

    2、void closeEvent(QCloseEvent *event)

    小部件关闭事件。默认实现接受事件。

    3、bool event(QEvent *event)

    处理事件。可处理以下事件:

    • QEvent::Polish
    • QEvent::GraphicsSceneMove:在场景中的位置改变。
    • QEvent::GraphicsSceneResize:在场景中的尺寸改变。
    • QEvent::Show:小部件显示在屏幕上了。
    • QEvent::Hide:小部件隐藏了。
    • QEvent::PaletteChange:调色板改变。
    • QEvent::FontChange:字体改变。
    • QEvent::EnabledChange:启用状态改变。
    • QEvent::StyleChange:样式改变。
    • QEvent::LayoutDirectionChange:布局方向改变。
    • QEvent::ContentsRectChange:内容边距/范围改变。

    4、void grabKeyboardEvent(QEvent *event)

    处理QEvent::GrabKeyboard (图形项获取键盘抓取)事件。

    5、void grabMouseEvent(QEvent *event)

    处理QEvent::GrabMouse(图形项获取鼠标抓取)事件。

    6、void hideEvent(QHideEvent *event)

    隐藏事件。在事件上调用 QEvent::accept() 或 QEvent::ignore() 无效。

    7、void moveEvent(QGraphicsSceneMoveEvent *event)

    移动事件。仅当图形项本身移动时才会传递此事件。调用 setTransform() 或移动任何图形项的祖先都不会影响图形项的本地位置。在事件上调用 QEvent::accept() 或 QEvent::ignore() 无效。

    8、void polishEvent()

    该事件在图形项构建之后的某个时间点由场景传递给图形项,此事件的作用是图形项在显示之前进行最后的初始化操作。

    9、void resizeEvent(QGraphicsSceneResizeEvent *event)

    调整大小事件。只有在本地调整小部件大小时才会传递此事件。在小部件或其任何祖先或视图上调用 setTransform() 不会影响小部件的本地大小。在事件上调用 QEvent::accept() 或 QEvent::ignore() 无效。

    10、bool sceneEvent(QEvent *event)

    QGraphicsItem::sceneEvent() 重新实现。QGraphicsWidget 的sceneEvent() 实现只是将事件传递给QGraphicsWidget::event()。不应该在 QGraphicsWidget 的子类中重新实现这个函数。

    11、void showEvent(QShowEvent *event)

    显示事件。在显示小部件之前传递此事件。 在事件上调用 QEvent::accept() 或 QEvent::ignore() 无效。

    12、void ungrabKeyboardEvent(QEvent *event)

    处理失去键盘抓取事件QEvent::UngrabKeyboard

    13、void ungrabMouseEvent(QEvent *event)

    处理失去鼠标抓取事件QEvent::UngrabMouse

    14、bool windowFrameEvent(QEvent *event)

    处理窗口框架的事件。它的基本实现提供了对默认窗口框架交互的支持,例如移动、调整大小等。

    展开全文
  • QT图形视图框架QT图形视图框架QT图形视图框架QT图形视图框架
  • Qt 图形视图框架 (一)

    万次阅读 多人点赞 2018-07-12 14:52:16
    如果要绘制成千上万的图形,并且对它们进行控制,比如拖动这些图形、检测它们的位置以及判断它们是否碰撞等,可以使用Qt提供的图形视图框架来进行设计。 图形视图框架提供了一个基于图形项的模型视图编程方法,主要...

        如果要绘制成千上万的图形,并且对它们进行控制,比如拖动这些图形、检测它们的位置以及判断它们是否碰撞等,可以使用Qt提供的图形视图框架来进行设计。

        图形视图框架提供了一个基于图形项的模型视图编程方法,主要由场景视图图形项三部分组成,这三部分分别由QGraphicsSceneQGraphicsViewQGraphicsItem这三个类来表示。多个视图可以查看一个场景,场景中包含各种各样几何形状的图形项。

        图形视图框架可以管理数量庞大的自定义2D图形项,并且可以与它们进行交互。使用视图部件可以使这些图形项可视化,视图还支持缩放与旋转。框架中包含了一个事件传播架构,提供了和场景中的图形项进行精确的双精度交互的能力。图形视图框架使用一个BSP(Binary Space Partitioning)树来快速发现图形项。可通过Graphics View Framework关键字查看相关帮助。

     场景

        QGraphicsScene提供了图形视图框架中的场景,场景拥有以下功能:

    1) 提供用于管理大量图形项的高速接口

    2) 传播事件到每一个图形项

    3) 管理图形项的状态,比如选择和处理焦点

    4) 提供无变换的渲染功能,主要用于打印


        QGraphicsScene的事件传播构架可以将场景事件传递给图形项,也可以管理图形项之间事件的传递。例如,如果场景在一个特定的点接收到了一个鼠标按下事件,那么场景就会把这个事件传递给该点的图形项。

        一个场景分为3层:图形项层(ItemLayer)、前景层(ForegroundLayer)、背景层(BackgroundLayer)。场景的绘制总是从背景层开始,然后是图形项层,最后是前景层。前景层和背景层都可以使用QBrush进行填充,比如使用渐变和贴图等。

    视图

        QGraphicsView提供了视图部件,它用来使场景中的内容可视化。可以连接多个视图到同一个场景来为相同的数据集提供多个视口。视图部件是一个可滚动的区域,它提供了一个滚动条来浏览大的场景。默认的QGraphicsView提供了一个QWidget作为视口部件,如果要使用OpenGl进行渲染,则可调用QGraphicsView::setViewport()设置QOpenGlWidget作为视口。QGraphicsView会获取视口部件的所有权。

        视图从键盘或者鼠标接收输入事件,然后会在发送这些事件到可视化场景前将他们转换为场景事件(将坐标转换为合适的场景坐标)。另外,使用视图的变换矩阵函数QGraphicsView::transform()时,可以通过视图来变换场景的坐标系统,这样便可以实现缩放和旋转等高级的导航功能。

    图形项

        QGraphicsItem是场景中图形项的基类。典型的形状的标准图形项有矩形(QGraphicsRectItem)、椭圆(QGraphicsEllipseItem)和文本项(QGraphicsTextItem)等。但只有编写自定义的图形项才能发挥QGraphicsItem的强大功能。

        QGraphicsItem主要支持如下功能:

    1) 鼠标按下、移动、释放、双击、悬停、滚轮和右键菜单事件

    2) 键盘输入焦点和键盘事件

    3) 拖放事件

    4) 碰撞检测

        除此之外,图形项还可以存储自定义的数据,可以使用setData()进行数据存储,然后使用data()获取其中的数据。

        要实现自定义的图形项,那么首先要创建一个QGraphicsItem的子类,然后重新实现它的两个纯虚公共函数:boundingRect()和paint(),前者用来返回要绘制图形项的矩形区域,后者用来执行实际的绘图操作。其中boundingRect()函数将图形项的外部边界定义为一个矩形,所有的绘图操作都必须限制在图形项的边界矩形中。这个矩形对于剔除不可见图形项、确定绘制交叉项目时哪些区域需要重新构建、碰撞检测机制都很重要。一定要保证所有绘图都在boundingRect()的边界之中,特别是当QPainter使用了指定的QPen来渲染图形的边界轮廓时,绘制的图形的边界线的一般会在外面,一半会在里面(例如使用了宽度为两个单位的画笔,就必须在boundingRect()里绘制一个单位的边界线),这也是在boundingRect()中要包含半个画笔宽度的原因。

        下面是纯虚函数的实现示例:

    QRectF MyItem::boundingRect() const
    {
        qreal penWidth = 1; //画笔宽度
        return QRectF(0 - penWidth / 2, 0 - penWidth / 2,
                      20 + penWidth, 20 + penWidth);
    }
    void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
    {
        painter->setBrush(Qt::red);
        painter->drawRect(0, 0, 20, 20);
    }

    图形视图框架的坐标系统

        图形视图框架基于笛卡尔坐标系统。图形视图框架中有3个有效的坐标系统:图形项坐标、场景坐标和视图坐标。进行绘图时,场景坐标对应QPainter的逻辑坐标,视图坐标对应设备坐标。

    图形项坐标

        图形项使用自己的本地坐标系统,坐标通常是以(0,0)为原点,而这也是所有变换的中心。当要创建一个自定义图形项时,只需要考虑图形项的坐标系统,而且一个图形项的边界矩形和图形形状都是在图形项坐标系统中的。

        图形项的位置是指图形项的原点在其父图形项或者场景中的位置。可以使用setPos()函数来指定图形项的位置,如果没有指定,默认出现在父图形项或者场景的原点处。

        子图形项的位置和坐标是相对于父图形项的,虽然父图形项的坐标变换会隐含地变换子图形项,但子图形项的坐标不会受到父图形项的变换的影响。例如,在没有坐标变换时,子图形项就在父图形项的(10,0)点,那么子图形项中的(0,10)点就对应了父图形项的(10,10)点。现在即使父图形项进行了旋转或者缩放,子图形项的(0,10)点仍对应着父图形项的(10,10)点。但是相对于场景,子图形项就会跟随父图形项的变换,例如,父图形项放大为(2x,2x),那么子图形项在场景中的位置就会变成(20,0),它的(10,0)点就会对应着场景中的(40,0)点。

        所有的图形项都会使用确定的顺序来进行绘制,这个顺序也决定了单击场景时哪个图形项会先获得鼠标输入。一个子图形项会堆叠在父图形项的上面,而兄弟图形项会以插入顺序进行堆叠。所有图形项都包含一个Z值来设置它们的层叠顺序,一个图形项的Z值默认为0,可以使用QGraphicsItem::setZValue()来改变一个图形项的Z值,从而使它堆叠到其兄弟图形项的上面(使用较大的Z值)或者下面(使用较小的Z值)。

    场景坐标

        场景坐标是所有图形项的基础坐标系统。场景坐标的原点在场景的中心,x和y坐标分别向右和向下增大。

    视图坐标

        视图坐标的每一个单位对应一个像素,原点(0,0)总在QGraphicsView视口的左上角,而右下角是(宽,高)。所有的鼠标事件和拖放事件最初都是使用视图坐标接收的。

    坐标映射

        不仅可以在视图、场景和图形项之间使用坐标映射,还可以在子图形项、父图形项或者图形项、图形项之间进行坐标映射。所有的映射函数都可以映射点、矩形、多边形和路径。例如要获取在视图中的一个椭圆形中包含的图形项,则可以先传递一个QPainterPath对象作为参数给mapToScene()函数,然后传递映射后的路径给QGraphicsScene::items()函数。

    图形视图框架的映射函数
    映射函数描述
    QGraphicsView::mapToScene( )从视图坐标系统映射到场景坐标系统
    QGraphicsView::mapFromScene( )从场景坐标系统映射到视图坐标系统
    QGraphicsItem;:mapToScene( )从图形项的坐标系统映射到场景的坐标系统
    QGraphicsItem;:mapFromScene( )从场景的坐标系统映射到图形项的坐标系统
    QGraphicsItem;:mapToParent( )从本图形项的坐标系统映射到其父图形项的坐标系统
    QGraphicsItem;:mapFromParent( )父图形项的坐标系统映射到本图形项的坐标系统
    QGraphicsItem;:mapToItem( )从本图形项的坐标系统映射到另一个图形项的坐标系统
    QGraphicsItem;:mapFromItem( )另一个图形项的坐标系统映射到本图形项的坐标系统

    事件处理与传播

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

    下面是一个应用实例:

    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);//一定要加上这个,否则在场景和图形项中就无法再接收到该事件了
    }
    

    鼠标拖动item后:


    键盘按下+ - 进行缩放后:



    展开全文
  • 目录名字Qt 图形视图框架中的事件处理和传播要点: Qt 图形视图框架中的事件处理和传播 图形视图框架在一些动画类的应用程序上经常会用到。该框架中的事件处理与传播机制也是经常会涉及。 程序设计核心在设计,而好...

    Qt 图形视图框架中的事件处理和传播

    图形视图框架在一些动画类的应用程序上经常会用到。该框架中的事件处理与传播机制也是经常会涉及。

    程序设计核心在设计,而好的设计,一定是建立在深刻的理解之上。理解Qt的事件处理和传播非常重要。

    这里《Qt Creator 快速入门 》的第11章有介绍,现在提炼要点如下:

    要点:

    1、图形视图框架中的事件传播的顺序是:视图–场景–图形项
    2、焦点决定事件如何传播:

    • 没有焦点,所有的键鼠事件都被丢弃。

    • 场景获得焦点,传播的终点就是场景。

    • 图形项获得焦点,传播的终点就是获得焦点的图形项。此时场景也是自动获得焦点的。

    • 场景会自动保存场景失去焦点前的图形项的焦点信息。

    3、鼠标有悬停事件,但是键盘没有。

    展开全文
  • 视图、水平标尺、垂直标尺用网格布局放置。 每当拖动视图的滚动条时,更新标尺的偏移量: connect(deviceGraphicsView->horizontalScrollBar(),&QScrollBar::valueChanged,[this,horizontalRuler] { ...
  • 前言: ...很久之前项目用过 这套框架, 好久没用了 在网上搜搜了 看了一看 这篇文章 把坐标系统和整体框架结构 讲出来了 简单明了 我转载过来了 ...这里我加一句 必须要重写这两个函数 如果不写编译器会报错 因为基类...
  • QT图形视图模型实现 说明 有用的DesignerPlugin部分为一个自定义的插件,用在ShapeItem里面。需要先编译这个项目,生成依赖库才可以在主工程里面执行。 SceneModle模块为图形视图部分的实现,目前增加了ImageItem,...
  • QT学习_QT图形视图

    2021-08-11 16:13:54
    QT图形视图框架Graphics View 一、主要特点 系统可以利用openGL工具改善绘图性能 支持事件传播体系结构 通过二元空间划分树提供快速的图元查找 二、三元素 场景类(QGraphicsScene):用于放置图元的容器,本身不...
  • QT笔记(5)——Qt图形视图框架实例

    千次阅读 2017-06-14 23:08:01
    Qt图形视图框架很强大,同时也很复杂,这里做了一个简单的练习,对图片加载,并移动放缩,的一个图片查看器;需要继承图元类; 下面直接贴源码了: 新建一个widget应用,然后添加如下:
  • 介绍Qt中的Graphics View Framework,涉及View、Scene、Item的关系,如何自定义QGraphicsItem、处理Item之间的关联、如何布局及定义自己的布局Item、如何变幻Item、如何应用动画、如何处理拖放、如何给Item应用图形...
  • Qt图形视图框架:QGraphicsScene详解

    千次阅读 2021-05-26 13:36:23
    它与视图一起用于可视化2D曲面上的图形图形项。 2、场景没有自己的视觉外观,只负责管理图形项。 3、场景的最大优势之一就是其快速有效地定位图形项的能力。即使场景中有数百万个图形项。 4、场景的另一个职责是...
  • 缓存图形加快渲染速度,当需要重新绘制时图形项使用缓存的图形。 1、NoCache 默认值,所有图形项缓存均已禁用。每次需要重新绘制图形项时,都会调用QGraphicsItem::paint()。 2、ItemCoordinateCache 为图形...
  • 本文需要了解基本的 Qt 图形视图框架结构和坐标系统 否则 你可能看不懂 还是看一些 官方demo 可以学到人家一些编码的东西 今天看到个好玩的 见下图 发现没 当小老鼠 碰到以后 耳朵就变红 也就是有碰撞检测机制 整个...
  • QT图形视图框架

    2021-04-15 10:05:56
    (1) 在Graphics View框架结构中,系统可以利用Qt绘图系统的反锯齿、OpenGL工具来改善绘图性能。 (2) Graphics View支持事件传播体系结构,可以使图元场景(scene)中的交互能力提高1倍,图元能够处理键盘事件和鼠标...
  • Qt图形视图框架到底效率如何?

    千次阅读 2017-03-10 11:59:43
    首先看看创建图元有多快? 创建10万个矩形图元耗时78ms。这速度完全没问题。 接着把创建的图元加入到场景中耗时多少?...创建10万个矩形图元并加入到场景中耗时13379ms 。... 然而我把图元的创建和添加至场景放置在...
  • 图形视图提供了一个外表(surface)来实现大量的客户所做的2D图形项的管理和相互的结合;一个视图窗口部件来使这些项可视化,并支持缩放和旋转。 该框架包括一个事件传播体系,可以使得场景中的项的交叉可以达到双...
  •  Qt为我们提供的图形视图框架真的是非常好用,它通过分解出视图、场景和图元降低了我们绘制图形的难度。它提供了强大图元控制能力,如快速查找图元、检测图元位置、检测图元碰撞等。除此以外图形视图框架还有一个很...
  • //图形项可发送位置变化信号 setFlag(QGraphicsItem::ItemIsSelectable); setFlag(QGraphicsItem::ItemIsFocusable); this->uuid = uuid; this->itemSize = QSizeF(100,100); isResizing = false; setZValue(1); } ...
  • Qt图形视图框架详解视频教程,介绍Qt中的Graphics View Framework,涉及View、Scene、Item的关系,如何自定义QGraphicsItem、处理Item之间的关联、如何布局及定义自己的布局Item、如何变幻Item、如何应用动画、如何...
  • 调用场景的advance()函数就会自动调用场景中所有图形项的advance()函数,
  • 图形视图框架的坐标系统和事件处理,项目名 myitem 功能: 获取鼠标位置下的 视图坐标、场景坐标和图形项坐标。 视图按键事件 图形项边界框,重绘。键盘按下事件,鼠标事件,鼠标悬停事件,上下文菜单事件。 ...
  • Qt图形视图框架三--坐标系统简介

    千次阅读 多人点赞 2017-07-27 12:17:48
    Qt图形视图框架 Graphics View 坐标系统
  • #资源达人分享计划#
  • 为了更好的看清效果我们重写了QGraphicsView类,在滚轮事件中对视图进行缩放。   接着重写QGraphicsLineItem的两个hover事件。 要想获取图元的hover事件还需要调用函数setAcceptHoverEvents(true)。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,869
精华内容 2,347
关键字:

qt图形视图