天天看點

學習QT之圖形視圖架構

Graphics View(圖形視圖)架構結構取代了之前版本中的QCanvas子產品,它提供基于圖元的模型/視圖程式設計,類似于QtInterView的模式/視圖結構,隻是這裡的資料是圖形。

一、圖形視圖體系結構

1、Graphics View架構結構的主要特點

Graphics View架構結構的主要特點如下:

(1)、在Graphics View架構結構中,系統可以利用Qt繪圖系統的反鋸齒、OPenGL工具來改善繪圖的性能。

(2)、Graphics View支援時間傳播體系結構,可以使圖元在場景(scene)中的互動能力提高1倍,圖元能夠處理鍵盤事件和滑鼠事件。其中,滑鼠事件包括滑鼠被按下、移動、釋放和輕按兩下,還可以跟蹤滑鼠的移動。

(3)、在Graphics View架構中,通過二進制控件劃分樹(Binary Space Partitioning,BSP)提供快速的圖元查找,這樣就能夠實時地顯示包含上百萬個圖元的大場景。

2、Graphics View架構結構的三元素

Graphics View架構結構主要包含三個類,即場景類(QGraphicsScene)、視圖類(QGraphicsView)和圖元類(QGraphicsItem),統稱為“三元素”。其中,場景類提供了一個用于管理位于其中的衆多圖元容器,視圖類用于顯示場景中的圖元,一個場景可以通過多個視圖表現,一個場景包括多個幾何圖形。Graphics View三元素之間的關系如下圖所示:

學習QT之圖形視圖架構

(1)、場景類:QGraphicsScene類

它是一個用于放置圖元的容器,本身是不可見的,必須通過與之相連的視圖類來顯示及與外界進行互動操作。通過​

​QGraphicsScene::addItem()​

​​可以添加一個圖元到場景中。圖元可以通過多個函數進行檢索。​

​QGraphicsScene::items()​

​​和一些重載函數可以傳回與點、矩形、多邊形或向量路徑相交的所有圖元。​

​QGraphicsScene::itemAt()​

​傳回指定點的頂層圖元。

場景類主要完成的工作包括提供對它包含圖元的操作接口和傳遞事件、管理各個圖元的狀态(如選擇和焦點處理)、提供無變換的繪制功能(如列印)等。

事件傳播體系結構将場景事件發送給圖元,同時也管理圖元之間的事件傳播。如果場景接收了在某一點的滑鼠點選事件,場景會将事件傳給這一點的圖元。

管理各個圖元的狀态(如選擇和焦點處理)。可以通過​

​QGraphicsScene::setSelectionArea()​

​​函數選擇圖元,選擇區域可以是任意的形狀,使用QPainterPath表示。若要得到目前選擇的圖元清單,則可以使用​

​QGraphicsScene::selectedItems()​

​​函數。可以通過​

​QGraphicsScene::setFocusItem()​

​​函數或​

​QGraphicsScene::focusItem()​

​函數。

如果需要将場景内容繪制到特定的繪圖裝置,則可以使用​

​QGraphicsScene::render()​

​函數在繪圖裝置上繪制場景。

(2)、視圖類:QGraphicsView類

它提供一個可視的視窗,用于顯示場景中的圖元。在同一個場景中可以有多個視圖,也可以為相同的資料集提供幾種不同的視圖。

QGraphicsView是可滾動的視窗部件,可以提供滾動條來浏覽大的場景。如果需要使用OpenGL,則可以使用​

​QGraphicsView::setViewport()​

​函數将視圖設定為QGLWidget。

視圖接收鍵盤和滑鼠的輸入時間,并将它們翻譯為場景事件(将坐标轉換為場景的坐标)。使用變換矩陣函數​

​QGraphicsView::matrix()​

​​可以變換場景的坐标,實作場景縮放和旋轉。QGraphicsView提供​

​QGraphicsView::mapToScene()​

​​和​

​QGraphicsView::mapFromScene()​

​函數用于與場景的坐标進行轉換。

(3)、圖元類:QGraphicsItem類

它是場景中各個圖元的基類,在它的基礎上可以繼承出各種圖元類,Qt已經預置的包括直線(QGraphicsLineItem)、橢圓(QGraphicsEllipseItem)、文本圖元(QGraphicsTextItem)、矩形(QGraphicsRectItem)等。當然,也可以在QGraphicsItem類的基礎上實作自定義的圖元類,即使用者可以繼承QGraphicsItem實作符合自己需要的圖元。

QGraphicsItem主要有以下功能:

  • 處理滑鼠按下、移動、釋放、輕按兩下、懸停、滾輪和右鍵菜單時間。
  • 處理鍵盤輸入事件。
  • 分組拖拽事件。
  • 分組。
  • 碰撞檢測。

此外,圖元有自己的坐标系統,也提供場景和圖元。圖元可以通過​

​QGraphicsItem::matrix()​

​函數來進行自身的交換,可以包含子圖元。

二、GraphicsView架構結構的坐标系統

Graphics View坐标基于笛卡爾坐标系,一個圖元的場景具有x坐标和y坐标。當使用沒有交換的視圖觀察場景時,場景中的一個單元對應螢幕上的一個像素。

三個Graphics View基本類有各自不同的坐标系,場景坐标、視圖坐标和圖元坐标。Graphics View提供了三個坐标系統之間的轉換函數。在繪制圖形時,Graphics View的場景坐标對應QPainter的邏輯坐标、視圖坐标和裝置坐标。

1、場景坐标

場景坐标是所有圖元的基礎坐标系統。場景坐标系統描述了頂層的圖元,每個圖元都有場景坐标和相應的包容框。場景坐标的原點在場景中心,坐标原點是x軸正方向向右,y軸正方向向下。

QGraphicsScene類的坐标系以中心為原點(0,0),如下圖示:

學習QT之圖形視圖架構

2、視圖坐标

視圖坐标是視窗部件的坐标。視圖坐标的機關是像素。QGraphicsView視圖的左上角是(0,0),x軸正方向向右,y軸正方向向下。所有的滑鼠事件最開始都是使用視圖坐标。

QGraphicsView類繼承自QWidget類,是以它與其他的QWidget類一樣,以視窗的左上角作為自己坐标系的原點,如下圖示:

學習QT之圖形視圖架構

3、圖元坐标

圖元使用自己的本地坐标,這個坐标通常以圖元中心為原點,這也是所有變換的原點。圖元坐标方向是x軸正方向向右,y軸正方向向下。建立圖元後,隻需注意圖元坐标就可以了,QGraphicsScene和QGraphicsView會完成所有的變換。

QGraphicsItem類的坐标系,在調用QGraphicsItem類的​

​paint()​

​函數重繪圖元時,則以此坐标系為基準,如下圖示:

學習QT之圖形視圖架構

根據需要,Qt提供了這三個坐标系之間的互相轉換函數,以及圖元與圖元之間的轉換函數,若需要從

QGraphicsItem坐标中的某一點坐标轉換到場景中的坐标,則可調用QGraphicsItem的​

​mapToScene()​

​​函數進行映射。而QGraphicsItem的​

​mapToParent()​

​函數則可将QGraphicsItem坐标系中的某點坐标映射到它的上一級坐标系中,有可能是場景坐标,也有可能是另一個QGraphicsItem坐标。

Graphics View架構提供了多種坐标變換的函數,總結如下:

映射函數 轉換類型
QGraphicsView::mapToScene() 從視圖到場景
QGraphicsView::mapFromScene() 從場景到視圖
QGraphicsItem::mapFromScene() 從場景到圖元
QGraphicsItem::mapToScene() 從圖元到場景
QGraphicsItem::mapToParent() 從圖元到父圖元
QGraphicsItem::mapFromParent() 從父圖元到子圖元
QGraphicsItem::mapToItem() 從本圖元到其它圖元