【Qt筆記】Graphics View Framework

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 仍是可使用這些遺留代碼)。app

 

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 內置了不少圖形,好比直線、多邊形等,它們都是繼承自QGraphicsItemcode

下面咱們經過一段代碼看看 Graphics View 的使用。對象

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()屬性:索引

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()一行,是由於咱們讓系統去決定視圖的最小尺寸(不然的話,咱們須要手動將窗口標題欄等的大小同時考慮設置)。

相關文章
相關標籤/搜索