1、Qt中提供了強大的2D繪圖系統,可以使用相同的API在屏幕和繪圖設備上進行繪制,它主要基於QPainter、QPaintDevice和QPaintEngine這三個類。其中QPainter用來執行繪圖操作;QPaintDevice提供繪圖設備,它是一個二維空間的抽象,可以使用QPainter在其上進行繪制;QPaintEngine提供了一些接口,可以用於QPainter在不同的設備上進行繪制。 QPainter一般在一個部件的重繪事件(Paint Event)的處理函數paintEvent()中進行繪制,首先要創建QPainter對象,然后進行圖形的繪制,最后銷毀QPainter對象。
2、在Qt窗口里面,(0, 0)點就是窗口的左上角,但這里是不包含外邊框的。而在MainWindow主窗口里面繪制時,左上角並不是指中心區域的左上角,而是包含了工具欄。
3、drawArc()畫弧線時,角度被分成了十六分之一,就是說,要想為30度,就得是30*16。
4、如果要繪制一個復雜的圖形,尤其是要重復繪制這樣的圖形,那么可以使用QPainterPath類,然后使用QPainter::drawPath()來進行繪制。QPainterPath類為繪制操作提供了一個容器,可以用來創建圖形並且重復使用。一個繪圖路徑就是由多個矩形、橢圓、線條或者曲線等組成的對象,一個路徑可以是封閉的,例如矩形和橢圓;也可以是非封閉的,例如線條和曲線。如果只是簡單的將幾個圖形拼接在一起,其實完全沒有必要用路徑,之所以要引入路徑,就是因為它的一個非常有用的功能:復制圖形路徑。創建路徑后,默認是從(0, 0)點開始繪制的。
5、Qt中每一個窗口都有一個坐標系統,默認的,窗口左上角為坐標原點,水平向右依次增大,水平向左依次減小,垂直向下依次增大,垂直向上依次減小。原點即為(0,0)點,以像素為單位增減,也可以稱為窗口坐標系。
6、默認的,QPainter在相關設備的坐標系統上進行繪制,在進行繪圖時,可以使用QPainter::scale()函數縮放坐標系統;使用QPainter::rotate()函數順時針旋轉坐標系統;使用QPainter::translate()函數平移坐標系統;還可以使用QPainter::shear()圍繞原點來扭曲坐標系統。這里要分清窗口坐標系和繪圖坐標系,起始時窗口坐標系與繪圖坐標系是重合的,當進行縮放、旋轉、平移及扭曲時變化的僅僅是繪圖坐標系,而窗口坐標系始終保持不變。
7、QPainter除了可以在QWidget等窗口部件上進行繪制以外,還可以在QPixmap、QImage等上面進行繪制,這些均稱為繪圖設備。為了表述方面,將QPixmap對象稱為畫布。畫布也有自己的坐標系統,畫布坐標系原點在畫布的左上角,當進行縮放、旋轉、平移及扭曲時變化的也僅僅是相對於畫布的繪圖坐標系。
8、QWidget和QPixmap各有一套坐標系統,它們互不影響。無論畫布在窗口的什么位置,它的坐標原點依然在左上角,為(0,0)點,沒有變。而在畫布上我們所得到的鼠標指針的坐標值是窗口坐標系統的,不是相對於畫布坐標系的。
9、整個圖形視圖結構主要包含三部分:場景(Scene)、視圖(View)和圖形項(Item),它們分別對應 QGraphicsScene 、QGraphicsView 、QGraphicsItem三個類。場景是管理圖形項的,所有的圖形項必須添加到一個場景中,但是場景本身無法可視化,我們要想看到場景上的內容,必須使用視圖。
10、QGraphicsItem類是所有圖形項的基類。圖形視圖框架對一些典型的形狀提供了一些標准的圖形項。比如上面我們使用的矩形(QGraphicsRectItem)、橢圓(QGraphicsEllipseItem)、文本(QGraphicsTextItem)等多個圖形項。但只有繼承QGraphicsItem 類實現我們自定義的圖形項時,才能顯示出這個類的強大。
11、在項目中添加新的C++類,類名設為 MyItem,基類設為QGraphicsItem。繼承QGraphicsItem類實現自定義的圖形項,必須先實現兩個純虛函數boundingRect()和paint(),前者用於定義Item的繪制范圍,后者用於繪制圖形項。
12、一個場景分為三個層:圖形項層(ItemLayer)、前景層(ForegroundLayer)和背景層(BackgroundLayer)。場景的繪制總是從背景層開始,然后是圖形項層,最后是前景層。對於前景層,我們一般不進行設置,或者像上面這樣設置為半透明的白色。
13、QGraphicsView 提供了視圖窗口部件,它使場景的內容可視化。你可以給一個場景關聯多個視圖,從而給一個數據集提供多個視口。視圖部件是一個滾動區域,就是說,它可以提供一個滾動條來顯示大型的場景。如果要使用OpenGL,你可以使用QGraphicsView::setViewport()函數來添加QGLWidget 。
14、在圖形視圖框架中,鼠標鍵盤等事件是從視圖進入的,視圖將它們傳遞給場景,場景再將事件傳遞給該點的圖形項,如果該點有多個圖形項,那么就傳給最上面的圖形項。所以要想使這個事件能一直傳播下去,我們就需要在重新實現事件處理函數時,在其最后將event參數傳給默認的事件處理函數。比如我們重寫了場景的鍵盤按下事件處理函數,那么我們就在該函數的最后寫上QGraphicsScene::keyPressEvent(event);一行代碼。
15、QGraphicsView默認使用一個QWidget作為視口部件,如果我們要使用OpenGL進行渲染,可以使用setViewport()函數來添加一個QGLWidget對象。看下面的例子。