Graphics View 提供了一种接口,用于管理大量自定义的 2D 图形元素,并与之进行交互;还提供了用于将这些元素进行可视化显示的观察组件,并支持缩放和旋转。我们通常所说的 Linux 的 KDE 桌面环境,就是建立在 Graphics View 基础之上的(尽管新版本的 KDE 有向 QML 迁移的趋势)。

Graphics View 框架包含了一套完整的事件体系,可以用于与场景中的元素进行双精度的交互。这些元素同样支持键盘事件、鼠标事件等。Graphics View 使用了 BSP 树(Binary Space Partitioning tree,这是一种被广泛应用于图形学方面的数据结构)来提供非常快速的元素发现,也正因为如此,才能够实现一种上百万数量级元素的实时显示机制。

Graphics View 最初在 Qt 4.2 引入,来取代 Qt 3 中的 QCanvas。当然,在最新的 Qt5 中,Qt3 的代码已经不能继续使用了(尽管在一定程度上, Qt4 还是可以使用这些遗留代码)。

Graphics View 是一个基于元素(item)的 MV 架构的框架。它可以分成三个部分:元素 item、场景 scene 和视图 view。

基于元素的意思是,它的每一个组件都是一个独立的元素。这是与我们之前讲到过的QPainter状态机机制不同。回忆一下,使用QPainter绘图,大多是采用一种面向过程的描述方式:首先使用drawLine()画一条直线,然后使用drawPolygon()画一个多边形。对于 Graphics View,相同的过程可以是,首先创建一个场景(scene),然后创建一个直线对象和一个多边形对象,再使用场景的add()函数,将直线和多边形添加到场景中,最后通过视图进行观察,就可以看到了。乍看起来,后者似乎更加复杂,但是,如果你的图像中包含了成千上万的直线、多边形之类,管理这些对象要比管理QPainter的绘制语句容易得多。并且,这些图形对象也更加符合面向对象的设计要求:一个很复杂的图形可以很方便的复用。

MV 架构的意思是,Graphics View 提供一个 model 和一个 view(正如 MVC 架构,只不过 MV 架构少了 C 这么一个组件)。所谓模型(model)就是我们添加的种种对象;所谓视图(view)就是我们观察这些对象的视口。同一个模型可以由很多视图从不同的角度进行观察,这是很常见的需求。使用 QPainter 很难实现这一点,这需要很复杂的计算,而 Graphics View 可以很容易的实现。

Graphics View 提供了QGraphicsScene作为场景,即是允许我们添加图形的空间,相当于整个世界;QGraphicsView作为视口,也就是我们的观察窗口,相当于照相机的取景框,这个取景框可以覆盖整个场景,也可以是场景的一部分;QGraphicsItem作为图形元件,以便添加到场景中去,Qt 内置了很多图形,比如直线、多边形等,它们都是继承自QGraphicsItem

下面我们通过一段代码看看 Graphics View 的使用。

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
 
    QGraphicsScene scene;
    scene.addLine(0, 0, 150, 150);
 
    QGraphicsView view(&scene);
    view.setWindowTitle("Graphics View");
    view.resize(500, 500);
    view.show();
 
    return app.exec();
}

这段代码很简单:首先创建一个场景,也就是QGraphicsScene对象。然后我们使用addLine()函数向场景中添加了一个直线,起始点和终点坐标分别是 (0, 0) 和 (150, 150)。可以想象,这是一个边长 150px 的正方形的对角线。通过这两步,我们已经有了场景和元素。之后,我们创建一个GraphicsView对象,绑定到一个场景上(也就是我们前面创建的 scene 对象)。注意,QGraphicsScene不是QWidget的子类,因此该构造函数并不是调用的QGraphicsView(QWidget *parent)。接下来,我们可以运行一下代码:

我们看到,这个直线自动在视图居中显示。这并不需要我们进行任何额外的代码。如果不想这么做,我们可以给 scene 设置一下sceneRect()属性:

 
 
1
2
3
4
5
6
7
8
    QGraphicsScene scene;
    scene.setSceneRect(0, 0, 300, 300);
    scene.addLine(0, 0, 150, 150);
 
    QGraphicsView view(&scene);
    view.setWindowTitle("Graphics View");
    // view.resize(500, 500);
    view.show();

不仅如此,我们还去掉了view.resize()一行。QGraphicsScenesceneRect属性供QGraphicsView确定视图默认的滚动条区域,并且协助QGraphicsScene管理元素索引。之所以去掉view.resize()一行,是因为我们让系统去决定视图的最小尺寸(否则的话,我们需要手动将窗口标题栏等的大小同时考虑设置)。

Qt 学习之路:Graphics View Framework的更多相关文章

  1. Qt 学习之路 2(30):Graphics View Framework

    Qt 学习之路 2(30):Graphics View Framework 豆子 2012年12月11日 Qt 学习之路 2 27条评论 Graphics View 提供了一种接口,用于管理大量自定义 ...

  2. Qt 学习之路 2(41):model/view 架构

    Qt 学习之路 2(41):model/view 架构 豆子 2013年1月23日 Qt 学习之路 2 50条评论 有时,我们的系统需要显示大量数据,比如从数据库中读取数据,以自己的方式显示在自己的应 ...

  3. Qt 之 Graphics View Framework 简介

    Graphics View Framework 交互式 2D 图形的 Graphics View 框架概述.自 Qt4.2 中引入了 Graphics View,以取代其前身 QCanvas.Grap ...

  4. Qt 学习之路 2(33):贪吃蛇游戏(3)

    Qt 学习之路 2(33):贪吃蛇游戏(3) 豆子 2012年12月29日 Qt 学习之路 2 16条评论 继续前面一章的内容.上次我们讲完了有关蛇的静态部分,也就是绘制部分.现在,我们开始添加游戏控 ...

  5. Qt 学习之路 2(32):贪吃蛇游戏(2)

    Qt 学习之路 2(32):贪吃蛇游戏(2) 豆子 2012年12月27日 Qt 学习之路 2 55条评论 下面我们继续上一章的内容.在上一章中,我们已经完成了地图的设计,当然是相当简单的.在我们的游 ...

  6. Qt 学习之路 2(31):贪吃蛇游戏(1)

    Qt 学习之路 2(31):贪吃蛇游戏(1) 豆子 2012年12月18日 Qt 学习之路 2 41条评论 经过前面一段时间的学习,我们已经了解到有关 Qt 相当多的知识.现在,我们将把前面所讲过的知 ...

  7. 《Qt 学习之路 2》目录

    <Qt 学习之路 2>目录 <Qt 学习之路 2>目录  豆子  2012年8月23日  Qt 学习之路 2  177条评论 <Qt 学习之路 2>目录 序 Qt ...

  8. qt 学习之路 :QML 语法

    前面我们已经见识过 QML 文档.一个 QML 文档分为 import 和对象声明两部分.如果你要使用 Qt Quick,就需要 import QtQuick 2.QML 是一种声明语言,用于描述程序 ...

  9. Qt 学习之路 2(59):使用流处理 XML

    Qt 学习之路 2(59):使用流处理 XML 豆子 2013年7月25日 Qt 学习之路 2 18条评论 本章开始我们将了解到如何使用 Qt 处理 XML 格式的文档. XML(eXtensible ...

  10. Qt 学习之路 2(58):编辑数据库外键

    Qt 学习之路 2(58):编辑数据库外键(skip) 豆子 2013年7月12日 Qt 学习之路 2 13条评论 前面几章我们介绍了如何对数据库进行操作以及如何使用图形界面展示数据库数据.本章我们将 ...

随机推荐

  1. DAC,MAC和SELinux,SEAndroid

    1. 被ROOT了怎么办 2. SELinux 3. SEAndroid 4. JB(4.3) MR2的漏洞弥补 ------------------------------------------- ...

  2. iOS: 学习笔记, 使用FMDatabase操作sqlite3

    使用FMDatabase操作sqlite3数据库非常简单和方便 // // main.m // iOSDemo0602_sqlite3 // // Created by yao_yu on 14-6- ...

  3. C#中的泛型-1

    在软件这个行业,做的越久,往往会觉得很多技术问题最终会偏向数据结构和算法. 记得曾经大学的一堂课上,老师讲了一个关于冒泡排序的算法,下面是课本上的标准实现. public class Sort { p ...

  4. 通过阅读ASP.NET MVC5 框架解密 路由的一点心得

    路由: 1.在ASP.NET中路由不专属与ASP.NET MVC,因为路由(Route)是在system.web 命名空间下的,所以传统的WebForm也可以使用路由. 2.什么叫做路由 采用某种机制 ...

  5. Spring3+MyBatis3整合log4j无法输出SQL语句问题的解决

    今天遇到了跟下面文章一模一样的问题,下面文章的解决方案很好,在这里记录保存一下. Spring3+MyBatis3整合无法输出SQL语句问题的解决

  6. Keil 的调试命令、在线汇编与断点设置

    上一讲中我们学习了如何建立工程.汇编.连接工程,并获得目标代码,但是做到这一 步仅仅代表你的源程序没有语法错误,至于源程序中存在着的其它错误,必须通过调试才能 发现并解决,事实上,除了极简单的程序以外 ...

  7. RemixOS Player 让用户在 Windows 上运行 Android App

    http://www.oschina.net/news/77154/remixos-player-windows-andriod-app

  8. 初次踏上GUI编程之路(有点意思,详细介绍了菜鸟的学习之路)

    初次踏上GUI编程之路 —— 我的Qt学习方法及对Qt认识的不断转变 -> 开始接触GUI与开始接触Qt: 话说,我第一次看见“Qt”这一个名词,好像是在CSDN网站的主页上吧,因为CSDN好像 ...

  9. QT内置的ICON资源

    QT内置的ICON资源保存在QStyle类里. 可以通过成员函数 QStyle::standardIcon 来获取. 保存的icon有: enum QStyle::StandardPixmap Thi ...

  10. WIA Property Constant Definitions

    (@http://msdn.microsoft.com/en-us/library/windows/desktop/ms630202(v=vs.85).aspx): const DeviceID = ...