您的位置:首页 > 编程语言 > Qt开发

Graphics View Framework 学习笔记——布局

2017-09-29 16:33 363 查看
Graphics View Framework 学习笔记——布局

由于工作需要前段时间自己研究学习了一下Qt中的一大重点内容模块:Graphics View Framework,工作之余整理跟大家分享一下,希望分享的内容可以帮助大家在工作中少走弯路,之中的内容如果有什么不足之处,也希望大家提出宝贵建议。

使用Qt做界面开发时,我相信大家都是从GUI方式的窗口开始进入Qt这所大世界的,所以大家在使用Qt的Graphics View Framework这套框架时,难免第一个想到就是如果把这个内容融入到GUI的世界中来。带着这个想法我们去Qt的助手进行搜索时,你一定会看到许多例子都是以下面的方式引领你去敲代码的:



看到show的那一刻你会想到什么,会不会认为这个家活是不是一个QWidget的派生类?



你看助手地帮助文档,你会发现QGraphicsView这个类最后竟然是从QWidget来的,并且还是一个带滚动条的QWidget,这样以后使用QScrollArea时就会省事很多,要知道我们使用QScrollArea时会有许多流程,简要代码如下:



而QGraphicsView一个类就解决了这堆代码的事情,让我们省很多事。上面说了这么多的内容,我想重点告诉大家的就时,使用Graphics View Framework这套框架想加入到GUI的界面中,你第一步要做的就是先来一个QGraphicsView的对象再进行后面的操作。

即使大家没有用过Graphics View Framework这套内容的知识,我们相信大家都知道里面有Scene、View和Item这三大部分组成,但他们之间是什么关系?先给大家看一个我理解的关系图:



在我看来QGrahpicsView就是一个跟GUI对接的大门,打开这座大门后,你会看到一个大大的庭院,而这个大庭院就是QGraphicsScene,这个庭院中可以放许多东西,这些可以被放置的东西我们可以理解成QGraphicsItem,这就是Scene、View和Item的关系。

在Graphics View Framework这个框架中,QGraphicsScene就是一个很大的画布,你可以在上面绘制各种元素对象Item,而这些Item展示方式在我看来有两种方式,一种是自由式的放置,另外一种使用布局来展示这些Item,这两种展示方式各有各自的应用场景,今天跟大家说的是使用布局方式展示这些Item。

布局方式

说到布局方式我们先想到的是GUI方式下常用的几种方式: QGridLayout、QHBoxLayout和QVBoxLayout,在Graphics View 这套框架下也有相应的布局:QGraphicsLinearLayout、QGraphicsGridLayout和QGraphicsAnchorLayout。

1、 QGraphicsLinearLayout

从自面的这理解我们看成线性布局,在构造的时候我们可以传递一个类型方式,即:



这个布局你就可以理解成是GUI里的QVBoxLayout和QHBoxLayout的结合体。

2、 QGraphicsGridLayout

这里可以理解成GUI里的QGridLayout

3、 QGraphicsAnchorLayout

这个是一个锚点布局,这个还没有用过,但给我的感觉应该会和QML中相关位置排列很像。

布局已经有了,我用使用什么来承载这个布局呢?这里就会需要我们的QGraphicsWidget来解决这个问题。我们去Qt助手中检索QGraphicsLinearLayout和QGraphicsGridLayout的内容时,在下面的介绍中你都会看到如何使用这个布局的简单下例子,代码内容如下:





布局类关系







布局的使用

1、 QGraphicsWidget设置布局



2、 Graphics Layout添加元素



到这里我们可以看出来,要在Graphics View下使用布局的内容,必须要有一个QGraphicsWiget,通过setLayout()的方式来设置一个布局QGraphicsLayout,而向Graphics Layout中添元素,我们又需要一个QGraphicsLayoutItem,而QGraphicsLayoutItem的数据类型只有两种:QGraphicsLayout和QGraphicsWidget,但在我们使用Graphics View 这套体系中,我们操作的最小元素对象只有QGraphicsItem,那我们怎么解决这个问题呢?

自定义QGraphicsLayoutItem

为解决上面我们说到的问题,我们可以使用多重的继承的方式来解决问题,下面我用一个例子简单的跟大家说明一下。



实现



到这里我们的自己需要的元素信息应该可以正常的展示到我们面前了,但我知道我们的工作中肯定不是只为了展示一个空壳,而是有许多的业务逻辑在其中掺杂,这时我们需要用到Qt中的信号与槽的机制,如果细心的话你会发现无论是QGraphicsItem还是QGraphicsLayoutItem都是没有继承QObject的,我们都知道要使用信号与槽的内容,还必须要有QObject来助阵才可以。





对于这种情况,我相信Qt自己也已经发现这个问题,于是Qt就给我们封装了一个QGraphicsObject的类解决这个问题,但实际工作中,仅仅是这样的内容我们可能还是达不到我们的要求,这时我们需要自己去继承QObject类,记得继承QObject一定要放在第一个位置,如下:



这样处理之后我们就可以使用信号与槽的机制来处理我们的业务内容了。

写在最后

在我们实际的工作中,我相信很多的需求用Qt现有给我们开放的内容很多时候根本达不到预期的要求,这时我们大部分都会选择自己去处理一下,这里支持的事件如下:

virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);

virtual bool sceneEvent(QEvent *event);

virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);

virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event);

virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);

virtual void dragMoveEvent(QGraphicsSceneDragDropEvent *event);

virtual void dropEvent(QGraphicsSceneDragDropEvent *event);

virtual void focusInEvent(QFocusEvent *event);

virtual void focusOutEvent(QFocusEvent *event);

virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event);

virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);

virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);

virtual void keyPressEvent(QKeyEvent *event);

virtual void keyReleaseEvent(QKeyEvent *event);

virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);

virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);

virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);

virtual void wheelEvent(QGraphicsSceneWheelEvent *event);

virtual void inputMethodEvent(QInputMethodEvent *event);

virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const;

virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);


上面的内容希望可以在工作中能有所帮助,也希望大家的提出宝贵建议。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  qt Graphics