如今基本上也已經到了2D繪圖部分的尾聲,所謂重頭戲都是在最後壓軸的,如今咱們就要來看看在繪圖部分功能最強大的Graphics View。咱們常常說KDE桌面,新版本的KDE桌面就是創建在Graphics View的基礎之上,可見其強大之處。
Qt的白皮書裏面這樣寫道:「Qt Graphics
View 提供了用於管理和交互大量定製的 2D 圖形對象的平面以及可視化顯示對象的視圖 widget,並支持縮放和旋轉功能。Graphics
View 使用 BSP(二進制空間劃分)樹形可很是快速地找到對象,所以即便是包含百萬個對象的大型場景,也能實時圖形化顯示。」
Graphics View是一個基於item的M-V架構的框架。
基於item意思是,它的每個組件都是一個item。這是與QPainter的狀態機不一樣。回憶一下,使用QPainter繪圖可能是採用一種面向過程的描述方式,首先使用drawLine()畫一條直線,而後使用drawPolygon()畫一個多邊形;而對於Graphics View來講,相同的過程能夠是,首先建立一個場景scene,而後建立一個line對象和一個polygon對象,再使用scene的add()函數將line和polygon添加到scene,最後經過視口view就能夠看到了。乍看起來,後者彷佛更加複雜,可是,若是你的圖像中包含了成千上萬的直線、多邊形之類,管理這些對象要比管理QPainter的draw語句容易得多。而且,這些圖形對象也更加符合面向對象的設計要求:一個很複雜的圖形能夠很方便的複用。
M-V架構的意思是,Graphics View提供一個model和一個view。所謂model就是咱們添加的種種對象,所謂view就是咱們觀察這些對象的視口。同一個model能夠由不少view從不一樣的角度進行觀察,這是很常見的需求。使用QPainter就很難實現這一點,這須要很複雜的計算,而Qt的Graphics View就能夠很容易的實現。
Graphics View提供了一個QGraphicsScene做爲場景,便是咱們添加圖形的空間,至關於整個世界;一個QGraphicsView做爲視口,也就是咱們觀察的窗口,至關於照相機的取景框,這個取景框能夠覆蓋整個場景,也能夠是場景的一部分;一些QGraphicsItem做爲圖形元件,以便scene添加,Qt內置了不少圖形,好比line、polygon等,都是繼承自QGraphicsItem。
下面咱們來看一下代碼:
![](http://static.javashuo.com/static/loading.gif)
#include <QtGui>
class DrawApp :
public QWidget {
public:
![](http://static.javashuo.com/static/loading.gif)
DrawApp();
protected:
void paintEvent(QPaintEvent *
event);
![](http://static.javashuo.com/static/loading.gif)
};
![](http://static.javashuo.com/static/loading.gif)
DrawApp::DrawApp()
![](http://static.javashuo.com/static/loading.gif)
{
![](http://static.javashuo.com/static/loading.gif)
}
void DrawApp::paintEvent(QPaintEvent *
event)
![](http://static.javashuo.com/static/loading.gif)
{
![](http://static.javashuo.com/static/loading.gif)
QPainter painter(
this);
![](http://static.javashuo.com/static/loading.gif)
painter.drawLine(10, 10, 150, 300);
![](http://static.javashuo.com/static/loading.gif)
}
int main(
int argc,
char *argv[])
![](http://static.javashuo.com/static/loading.gif)
{
![](http://static.javashuo.com/static/loading.gif)
QApplication a(argc, argv);
![](http://static.javashuo.com/static/loading.gif)
QGraphicsScene *scene =
new QGraphicsScene;
![](http://static.javashuo.com/static/loading.gif)
scene->addLine(10, 10, 150, 300);
![](http://static.javashuo.com/static/loading.gif)
QGraphicsView *view =
new QGraphicsView(scene);
![](http://static.javashuo.com/static/loading.gif)
view->resize(500, 500);
![](http://static.javashuo.com/static/loading.gif)
view->setWindowTitle(
"Graphics View");
![](http://static.javashuo.com/static/loading.gif)
view->show();
![](http://static.javashuo.com/static/loading.gif)
DrawApp *da =
new DrawApp;
![](http://static.javashuo.com/static/loading.gif)
da->resize(500, 500);
![](http://static.javashuo.com/static/loading.gif)
da->setWindowTitle(
"QWidget");
![](http://static.javashuo.com/static/loading.gif)
da->show();
return a.exec();
![](http://static.javashuo.com/static/loading.gif)
}
爲了突出重點,咱們就直接include了QtGui,不過在實際應用中不建議這麼作。這裏提供了直線的兩種實現:一個是DrawApp使用咱們前面介紹的技術,重寫paintEvent()函數,這裏就不在贅述,重點來看main()函數裏面的實現。
首先,咱們建立了一個QGraphicsScene做爲場景,而後在scene中添加了一個直線,這樣就把咱們須要的圖形元件放到了scene中。而後建立一個QGraphicsView對象進行觀察。就這樣,咱們就是用Graphics View搭建了一個最簡單的應用。運行這個程序來看結果:
第一張圖是Graphics View的,第二個是DrawApp的。雖然這兩個直線是一樣的座標,可是,DrawApp按照原始座標繪製出了直線,而Graphics View則按照座標繪製出直線以後,自動將直線居中顯示在view視口。你能夠經過拖動Graphics View來看直線是一直居中顯示的。
這裏僅僅是一個很簡單的對比,不過你已經能夠看到Graphics View功能的強大。僅這一個居中的操做,若是你是用QPainter,就須要很大的計算量了!固然,若是你不須要這種居中,Graphics View也是能夠像QPainter繪製的同樣進行顯示的。