原文地址:http://devbean.blog.51cto.com/448512/241186
绘图部分功能最为强大的便是Graphics View Framework.
一 基本概念
1.Qt Graphics View作用
Qt Graphics View 提供了用于管理和交互大量定制的 2D 图形对象的平面以及可视化显示对象的视图 widget,并支持缩放和旋转功能。Graphics View 使用 BSP(二进制空间划分)树形可非常快速地找到对象,因此即使是包含百万个对象的大型场景,也能实时图形化显示。
2.Graphics View是一个基于item的M-V架构的框架。
(1)基于item含义
它的每一个组件都是一个item。
这是与QPainter的状态机不同。
二者的过程不同:
使用QPainter绘图多采用面向过程的描述方式,首先使用drawLine()画一条直线,然后使用drawPolygon()画一个多边形;
对于Graphics View来说,过程是:首先创建一个场景scene,然后创建一个line对象和一个polygon对象,再使用scene的add()函数将line和polygon添加到scene,最后通过视口view就可以看到了。
二者效率对比:
看起来,后者似乎更加复杂。但是,如果你的图像中包含了成千上万的直线、多边形之类,管理这些对象要比管理QPainter的draw语句容易得多。
而且这些图形对象也更加符合面向对象的设计要求:一个很复杂的图形可以很方便的复用。
(2)M-V架构
Graphics View提供一个model和一个view。所谓model就是我们添加的种种对象,所谓view就是我们观察这些对象的视口。同一个model可以由很多view从不同的角度进行观察,
这是很常见的需求。使用QPainter就很难实现这一点,这需要很复杂的计算,而Qt的Graphics View就可以很容易的实现。
3.QGraphicsScene
Graphics View提供了一个QGraphicsScene作为场景,即是我们添加图形的空间,相当于整个世界;
一个QGraphicsView作为视口,也就是我们观察的窗口,相当于照相机的取景框,这个取景框可以覆盖整个场景,也可以是场景的一部分;
一些QGraphicsItem作为图形元件,以便scene添加,Qt内置了很多图形,比如line、polygon等,都是继承自QGraphicsItem。
二 代码展示
1.所有代码
(1)drawapp.h
#ifndef DRAWAPP_H
#define DRAWAPP_H
#include <QWidget>
class DrawApp : public QWidget
{
Q_OBJECT
public:
DrawApp(QWidget *parent = 0);
~DrawApp();
protected:
void paintEvent(QPaintEvent *event);
};
#endif // DRAWAPP_H
(2)drawapp.cpp
#include "drawapp.h"
#include<QPainter>
DrawApp::DrawApp(QWidget *parent)
: QWidget(parent)
{
}
DrawApp::~DrawApp()
{
}
void DrawApp::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawLine(10, 10, 150, 300);
}
(3)main.cpp
#include "drawapp.h"
#include <QApplication>
#include<QGraphicsScene>
#include<QGraphicsView>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene *scene = new QGraphicsScene;
scene->addLine(10, 10, 150, 300);
QGraphicsView *view = new QGraphicsView(scene);
view->resize(500, 500);
view->setWindowTitle("Graphics View");
view->show();
DrawApp *da = new DrawApp;
da->resize(500, 500);
da->setWindowTitle("QWidget");
da->show();
return a.exec();
}
2.运行结果
(1)QWidget
(2)Graphics view
3.代码详解
(1)
DrawApp *da = new DrawApp;
da->resize(500, 500);
da->setWindowTitle("QWidget");
da->show();
return a.exec();
这段代码采用以前的技术,重写paintEvent事件。
(2)
QGraphicsScene *scene = new QGraphicsScene;
scene->addLine(10, 10, 150, 300);
QGraphicsView *view = new QGraphicsView(scene);
view->resize(500, 500);
view->setWindowTitle("Graphics View");
view->show();
这段代码采用Graphics View Framework技术。
步骤一: 创建一个QGraphicsScene作为场景
QGraphicsScene *scene = new QGraphicsScene;
步骤二: 在scene中添加了一个直线
scene->addLine(10, 10, 150, 300);
经过上面两步,我们就把所需的图形元件放到了scene中
步骤三 : 创建一个QGraphicsView对象用于观察
QGraphicsView *view = new QGraphicsView(scene);
步骤四:展示view
view->show();
三 知识讲解
在上面的两幅图中,虽然这两个直线是同样的坐标。
但是,DrawApp按照原始坐标绘制出了直线,而Graphics View则按照坐标绘制出直线之后,自动将直线居中显示在view视口。拖动Graphics View直线也是一直居中显示的。
同时,用户也可以设置Graphics View图形不居中