我朋友的丈夫3_一个朋友妈妈8_HD中文字幕在线观看,蓝川美夏,日本三级电影手机在线观看,日韩伦理电影网站

資源中心

Resource Centers

2021-01-13

QT繪圖之圖形視圖


在Qt中我們可以通過QWidget的派生類,重寫paintEvent()函數,使用QPainter繪制我們想要的任何內容。這種方法對于從QWidget派生的窗口部件很理想,但如果要繪制大量獨立的項,向用戶提供與圖形項交互(如鼠標交互等,通常需要大量的工作。


圖形視圖架構,則完美地滿足了基于圖形項的高性能繪制和交互的需求。


在Qt4中,圖形視圖基于Qt中GUI和QtCore模塊,該架構的設計取代并超越了Qt3的QCanvas。它提供了一個平臺,用于大量自定義2D圖元的管理與交互,使用一個BSPBinary Space Partitioning - 二叉空間分割)樹,以提供對圖形元素的快速查找。正因如此,它可以使超大的場景實時地可視化,即使其包含數百萬的圖元。


框架包括一個事件傳播架構,支持場景(Scene)中的圖元(Item)進行精確的雙精度交互功能。圖元可以處理鍵盤事件、鼠標按下、移動、釋放和雙擊事件,同時也能跟蹤鼠標移動。



1

圖形視圖架構


圖形視圖的 場景視圖、 圖元,作為圖形視圖架構的三要素。其中每個圖元從抽象類(QGraphicsItem)派生而來,場景(QGraphicsScene)作為模型容納管理各個繪制項,視圖(QGraphicsView) 用來可視化顯示數據,如有需要,我們可以在多個不同的視圖內顯示同一場景。


場景


QGraphicsScene提供了圖形視圖場景。它提供了一個快速的接口,用于管理大量圖元、向每個圖元傳遞事件、管理圖元的狀態(tài),如:選中、焦點處理等。


場景是QGraphicsItem對象的容器。通過調用QGraphicsScene::addItem()將圖元添加到場景中后,你就可以通過調用場景中的不同的查找函數來查找其中的圖元。


QGraphicsScene::items()函數及其重載函數可返回所有圖元。包括:點、矩形等;通過QGraphicsScene::itemAt()接口返回在特定點上最上面的圖元。所有找到的圖元按照層疊遞減的排列順序(即:最先返回的圖元是最頂層的,最后返回的則是最底層的)


QGraphicsScene的事件傳遞機制負責將場景事件傳遞給圖元,同時也管理圖元之間的傳遞。如果場景在某個位置得到一個鼠標按下事件,就將該事件傳遞給這個位置上的圖元。QGraphicsScene同時還管理某些圖元的狀態(tài),例如:圖元的選中和焦點。


視圖


提供一個可視的窗口,用于顯示場景中的圖元。對于同一個場景,可以提供多個不同/相同的視圖來顯示其元素。


QGraphicsView是可滾動的窗口部件,用來提供滾動條以瀏覽大的場景。如需使用OpenGL,可用QGraphicsView::setViewport()將視圖設置為QGLWidget。如果你希望OpenGL具有反鋸齒,則需要OpenGL支持采樣緩沖。視圖的類層次圖如下圖:

圖1.png


圖元


QGraphicsItem是場景中圖元的基類。其中提供了一些典型形狀的標準圖元,例如:矩形 、橢圓 、文本項 。當然你也可以自定義圖元項。除此之外,QGraphicsItem還支持以下特性:鼠標按下、移動、釋放和雙擊事件,以及鼠標懸浮事件、滾輪事件和上下文菜單事件;鍵盤輸入焦點和鍵盤事件;拖放;分組:通過父子關系或QGraphicsItemGroup;碰撞檢測。


每個圖元項都有一個z值,z值較大的項會被繪制在z值較小的項之上,這樣就可以調整覆蓋圖元項的顯示順序;每個圖元項可以是場景或者另一個項的子對象,當對一個項進行了矩陣變換,該項的所有子對象會自動的應用該變換,遞歸應用至最深層次的子孫對象。


如果讓子項忽略所有父項的變換,可以通過調用QGraphicsItem::setFlag(QGraphicsItem::ItemIgnoresTransformations)來實現(xiàn)。Qt中圖元項的類層次結構如下圖所示(具體用法請參見Qt幫助文檔)

圖2.png
圖3.png


2

圖形視圖坐標系


圖形視圖基于笛卡兒坐標系,場景中圖元的位置和幾何形狀由兩組數據來表示:X坐標和Y坐標。當使用一個未轉換的視圖來觀察一個場景,場景中的一個單元將會由場景上的一個像素表示。圖形視圖中使用了三種有效的坐標系 圖元坐標、  場景坐標 視圖坐標


圖元坐標


圖元的繪制在自己的局部坐標系。它們的坐標通常圍繞它們的中心點(0, 0),并且這也是所有轉換的中心。創(chuàng)建自定義圖元時,只需考慮圖元坐標即可。QGraphicsScene和QGraphicsView會為你實現(xiàn)所有相關的轉換,這樣一來,實現(xiàn)自定義圖元就容易多了。圖元綁定的矩形(boundingRect())或形狀區(qū)域(shape())也是項坐標系統(tǒng)的。


子坐標是相對于父坐標而言的,如果子坐標沒有轉換,那么子坐標和父坐標的差異就和圖元在父坐標中的距離一樣,圖元的位置(pos)是圖元的中心點在其父坐標系下的坐標,有時也被稱為父坐標。


如果這個圖元直接加到場景中則它的位置在場景坐標中,由于圖元的位置和轉換是相對于父圖元來說的,因此,雖然父圖元的轉換隱式地轉換了子圖元,但是子圖元的坐標不會因其轉換而受影響。不過相對于場景來說,子圖元將隨著父圖元進行轉換和偏移 。圖元坐標系如下圖所示:


圖4.png


場景坐標系


場景為所有圖元提供了基礎坐標系。場景坐標系描述了每個頂層圖元的位置,同時構成了從視圖傳遞到場景中所有事件的基礎。其中每個圖元都有一個場景位置以及坐標系下的矩形邊界(QGraphicsItem::scenePos()QGraphicsItem::sceneBoundingRect()),場景坐標系如下圖所示:


圖5.png


視圖坐標系


視圖坐標是窗口的坐標,視圖坐標中的每個單位對應一個像素。對于該坐標系來說較特殊的一點是:它相對于視口,不會受被觀察的場景所影響。QGraphicsView以窗口的左上角作為自己坐標系的原點總是(0, 0),右下角總是(width, height)。所有的鼠標事件和拖拽事件都以視圖坐標接收到的,你需要將這些坐標映射到場景,以便于和圖元進行交互。視圖坐標系如下圖:

圖6.png


坐標映射


圖7.png


3

事  件


當QGraphicsView接收到Qt鼠標、鍵盤和拖放事件(QMouseEvent、QKeyEvent、QDragEvent等)時,它會將其轉換為QGraphicsceneEvent子類的實例,并轉發(fā)到它顯示的QGraphicscene。然后,場景再將事件轉發(fā)到相關圖元項,即:視圖->場景->圖元。圖形視圖中事件的類層次如下:


圖8.png


4

動  畫


圖形視圖在幾個層面上提供了對動畫的支持。實現(xiàn)圖元動畫有三種方法:


1)  使用Qt中的Animation Framework框架,QPropertyAnimation可以為任何QObject屬性實現(xiàn)動畫效果,所以你的圖元必須繼承QObject和QGraphicsItem。

2)  創(chuàng)建一個自定義圖元,從QObjcet和QGraphicsItem繼承,該圖元可以通過定時來驅動實現(xiàn)動畫。

3)  調用QGraphicsScene::advance()從而依次調用QGraphicsItem::advance();


5

示  例


自定義圖元示例

圖9.png


構建一個場景視圖示例


向場景中添加了一個矩形,一個圓:

圖10.jpg


* 注: 本文介紹基于Qt4.8.6.


更多服務

More services