繪圖架構Graphics View介紹
在Qt界面庫中,對於圖形的繪製,在前面一篇文章中(可參考:),介紹了一種使用QPainter實現普通二維圖形的繪製方法,該方法在paintEvent事件裡編寫繪圖程序,其本質繪製的圖形是位圖,這種方法更適合於繪製複雜度不高的固定圖形,並且不能實現圖項的選擇、編輯、拖放、修改等交互功能。
對於需要繪製大量的、需要交互的圖形,可使用Graphics View繪圖架構,它是一種基於圖形項(Graphics Item)的模型/視圖模式,這種方式可以在一個場景中可繪製大量圖元項,且每個圖元項都是可選擇、可交互的。
在Graphics View繪圖架構中,主要涉及到下面三個類的使用:
1. 場景類(QGraphicsScene):該類提供繪圖場景(Scene),場景是不可見的,是一個抽象的管理圖形項的容器,可向場景中添加圖形項,獲取場景中的某個圖形項等;
2. 視圖類(QGraphicsView):該類提供繪圖的視圖(View)組件,用於顯示場景中的內容。可以為一個場景設置幾個視圖,用於對同一個數據集提供不同的觀察方式;
3. 圖形項類(QGraphicsItem):該類提供了一些基本的圖形元件,也可在此基礎上自定義圖形項,它支持各種事件的響應,如滑鼠事件、鍵盤事件、拖放事件等,以實現圖形的交互功能。
在Graphics View繪圖架構中涉及到了3個坐標系,即場景坐標、視圖坐標及圖形項坐標。其中,場景坐標類似於QPainter的邏輯坐標,一般以場景的中心為原點;視圖坐標是窗口界面的物理坐標,其左上角為原點坐標;圖形項坐標是局部邏輯坐標,通常以圖件的中心為原點。
下面給出一個在Python語言下結合PyQt界面庫,使用Graphics View架構進行繪圖的例子,例子中也涉及到了坐標系統的理解。
示例說明
該例運行界面如下圖所示:
在主窗口的視圖上顯示了四個圖元(圖元項),包括三個可選擇、可移動且不同填充顏色的圓形,一個標識場景大小的矩形框。當滑鼠移動時,在狀態欄中實時顯示當前滑鼠位置的三種坐標,即視圖(View)坐標、場景(Scene)坐標及圖形項(Item)坐標。
本例主界面的Python程序使用純代碼方式實現,下面給出該例的實現過程。
自定義的視圖類設計
由於在視圖中需要監視獲取當前的滑鼠移動位置,故設計了一個單獨的基於QGraphicsView基類的視圖類,其實現代碼如下圖所示:
該類中定義了一個自定義信號sigMouseMovePoint,當滑鼠移動時,在mouseMoveEvent事件中,將當前的滑鼠位置發送出去。
主窗口類設計
主窗口基於QMainWindow類,在其中添加一個視圖控制項用於顯示圖元及一個狀態欄控制項用於顯示坐標。其實現代碼如下圖所示:
其主要代碼解釋如下:
(1)第25-31行,窗口類的初始化函數,並且設置了視圖類sigMouseMovePoint信號響應的槽函數。
(2)第33-48行,在主窗口上創建視圖控制項並將其設置為中心部件,設置狀態欄信息。
(3)第50-67行,在視圖中完成圖形的繪製。先創建視圖的場景,然後創建矩形框,其大小為場景大小,將矩形框添加到場景中,然後依次創建三個圓形,其位置分別為矩形框的左邊界、中心及右邊界,設置為可移動、可選擇及可設置焦點屬性,最後將其添加到場景中。
(4)第69-76行,當視圖中滑鼠移動時,獲取三種坐標。其中參數pt為視圖坐標。使用視圖類的mapToScene函數可將其轉換為場景坐標。根據場景坐標可獲取當前滑鼠位置的圖形項,進而由圖形項類的mapFromScene函數可得到當前圖形項的坐標。得到這些坐標後可在狀態欄中進行顯示。
完整測試代碼
程序完整測試代碼如下圖所示:
運行後就會出現本文開頭所示的軟體界面,且在主界面上移動滑鼠時,可在狀態欄中實時得到三種坐標。
總結
本文例子演示了在Python+PyQt架構下,使用Graphics View繪圖架構進行簡單繪圖的過程,並在例子中給出了三種坐標的轉換方法。其繪圖過程基本上可總結為下面幾個步驟,即創建視圖、創建場景、關聯場景到視圖、在場景中創建各種圖形項、完成圖形的顯示等。
本文由編碼那些事原創,請關注+轉發+收藏+點讚,帶你一起長知識!