Graphics View框架

 

Qt4.2開始引入了Graphics View框架用來取代Qt3中的Canvas模塊,並在不少地方做了改進,Graphics View框架實現了模型-視圖結構的圖形管理,能對大量圖元進行管理,支持碰撞檢測,座標變換和圖元組等多種方便的功能。GraphicsView中加強的表現系統能夠利用Qt4繪圖系統的反鋸齒,OpenGL工具來改善繪圖性能,Graphics View支持事件傳播體系結構,能夠利用圖元在場景(scene)中的到提升了一倍的精確交互能力,圖元可以處理鍵盤事件,鼠標按下,移動,釋放,雙擊事件,也能跟蹤鼠標的移動,在Graphics View框架中,經過BSP(二元空間劃分樹)來提供快速的圖元查找.這樣就能實時地顯示大場景,甚至上百萬個圖元。GraphicsView框架提供基於圖元的視圖-模型編程,相似於QtInterView的模型,視圖結構,只是這裏的數據是圖形,Graphics View框架中包含三個主要的類,QGraphicsScene,QGraphicsView,QGraphicsItem,分別是場景,視圖和圖元。一個場景能夠經過多個視圖表現,一個場景中包括多個幾何圖形。 
--------------------------- 
1 場景QGraphicsScene 
QGraphicsScene類實現QGraphics View中的場景,場景類完成以下功能: 
提供管理大量圖元的快速接口 
傳播事件給場景中的每一個圖元 
管理圖元狀態,如選擇焦點處理 
提供無變換的繪製功能,如打印 
場景是QGraphicsItem對象的容器,經過函數QGraphicsScene::addItem()能夠加入一個圖元到場景中,圖元能夠經過多個函數進行檢索,QGraphicsScene::items()和一些重載的函數能夠返回點,矩形,多邊形或向量路徑相交的全部圖元,QGraphicsScene::itemAt()返回指定點的頂層圖元。QGraphicsScene的事件傳播體系結構將場景事件發送給圖元,同時也管理圖元之間的事件傳播,若是場景收到了某一點的鼠標單擊事件,場景會把事件傳給在這一點的圖元。QGraphicsScene負責管理一些圖元的狀態,如圖元選擇和焦點。能夠經過QGraphicsScene::setSeletionArea()函數選擇圖元,選擇區域能夠是任意的形狀,使用QPainterPath表示,要獲得當前選擇的圖元列表能夠使用QGraphicsScene::selectedItems().QGraphicsScene還管理圖元的鍵盤輸入焦點狀態,能夠經過QGraphicsScene::setFocusItem()函數或者QGraphicsItem::setFoucs()函數來設置圖元的焦點,得到當前具備焦點的圖元使用函數QGraphicsScene::foucsItem().若是須要在場景內繪製到特定的繪圖設備,能夠使用QGraphicsScene::render()函數在繪圖設備上繪製場景。 
2 視圖 
QGraphics View是視圖窗口部件,他使場景內容可視化,能夠鏈接幾個視圖到一個場景,也能夠爲相同的數據源的數據集提供集中不一樣的視口。QGraphicsView是可滾動的窗口部件,能夠提供滾動條來瀏覽大的場景。若是須要使用OpenGL,能夠使用QGraphicsView::setViewport()將適口設置爲QGLWidget.視圖接收鍵盤和鼠標的輸入事件,並把它翻譯爲場景事件。(將座標轉換爲場景的座標)。使用變換矩陣函數QGraphicsView::martix能夠變換場景的座標。經過這種方法能夠實現場景的縮放和旋轉。QGraphicsView提供QGraphicsView::mapToScene()和QGraphicsView::mapFromScene()來和場景的座標進行轉換。 
3 圖元 
QGraphicsItem是圖元的基類。QGraphics View框架提供了幾種標準的圖元。矩形(QGraphicsRectItem),橢圓(QGraphcisEllipseItem),文本圖元(QGraphicsTextItem)等。用戶能夠繼承QGraphicItem實現符合本身的圖元。QGraphicsItem具備下列功能: 
處理鼠標按下,移動,釋放,雙擊,懸停,滾動和右鍵菜單事件。 
處理鍵盤輸入事件 
處理拖放事件  分組:  碰撞檢測 
圖元有本身的座標系統,也提供場景和圖元。圖元和圖元之間的座標變換函數,圖元也能夠經過QGraphicsItem::martix()來進行自身的變換。圖元能夠包含子圖元。
  ---------------------------------------------------------------------- 
Graphics View座標系統 
Graphics View座標系基於笛卡爾座標系,一個圖元的場景座標具備x座標和y座標。當使用沒有變換的視圖觀察場景時,場景中的一個單元對應屏幕上的一個像素。在Graphics View中有三個有效的座標系統,圖元座標,場景座標,和視圖座標。Graphics View提供了三個座標系統之間的轉換函數。在繪製圖形所時,QGraphics View的場景座標對應QPainter的邏輯座標,視圖座標和設備座標相同。 
1 圖元座標 
圖元使用本身的本地座標,這個座標系統一般以圖元中心爲原點,這也是全部座標變換的原點,圖元座標方向是x軸正方向向右。y軸正方向下。建立圖元后,之須要注意圖元的座標就能夠了。QGraphicsScene和QGraphicsView會完成全部的變換。
2 場景座標 
場景座標是全部圖元的基礎座標系統。場景座標系統描述了頂層圖元。每一個圖元都有場景座標和相應的包容框,場景座標的原點在場景中心. 
3 視圖座標 
視圖座標是窗口部件的座標,視圖座標的單位是像素,QGraphicsView的左上角是(0,0).全部鼠標事件最開始都使用視圖座標。 
4 座標映射 
在Graphics View框架中,常常須要將多種座標變換,從場景到圖元,從圖元到圖元,從視圖到場景  QGraphics View框架座標變換函數 
-------------------------------------------------- ----------------------- 
QGraphicsView::mapToScene() 
QGraphicsView::mapFromScene() 
QGraphicsItem::mapFromScene() 
QGraphicsItem::mapToScene() 
QGraphicsItem::mapToParent() 
QGraphicsItem::mapFromParent(); 
QGraphicsItem::mapToItem(); 
QGraphicsItem::mapFromItem(); 
-------------------------------------------------- ----------------------- 
深刻 QGraphics View 
1 縮放和旋轉 
GraphicsView經過QGraphicsView::setMartix()支持同QPainter同樣的幾何變換。當進行視圖變換時,QGraphicsView保持視圖中心。經過應用變換,能夠很容易實現縮放和旋轉。  下面說明如何經過縮放和旋轉槽來實現對視圖的縮放和旋轉。 
class View::public QGraphicsView  { 
Q_OBJECT  ..... 
public slots: 
void zoomIn(){scale(1.5,1.5);}; 
void zoomOut(){scale(1/1.5,1/1.5);} 
void rotateLeft(){rotate(-90);} 
void rotateRight(rotate(90);)  ....  }; 
將槽和具備autoRepeat屬性的QToolButton進行鏈接,就能夠實現連續的縮放操做。 
2 光標和和工具提示 
和QWidget同樣,QGraphicsItem支持圖元特定的光標(應用QGraphicsItem::setCursor())和工具提示(QGraphicsItem::setToolTip()).在鼠標進入圖元區域時激活相應的光標和工具提示。 
3 動畫 
QGraphics View支持幾種不一樣級別的動畫,能夠將動畫路徑經過QGraphicsItemAnimation和圖元關聯。這是一使時間線性控制的圖元在全部平臺上的速度一致。QGraphcisItemAnimation容許建立圖元的路徑,包括位置,旋轉,縮放,扭曲,平移等操做的路徑。即在不一樣的時候進行不一樣的變換。動畫經過經常使用QTimeLine來控制,也能夠用QSlider來控制。也能夠建立從QObject和QGraphicsItem繼承的圖元,此類圖元能夠設置本身的定時器,經過QObject::timeEvent()來控制動畫。 
4 OpenGL繪製 
要使用OpenGL繪製,能夠調用QGraphicsView::setViewport()來設置QGLWidget做爲QGraphicsView的視口,若是須要在OpenGL中打開反鋸齒,能夠使用QGLFormat::sampleBuffer()來使用OpenGL的採用緩衝區(samplebuffer); 
5 圖元組 
使用圖元組能夠將圖元組合在一塊兒,對圖元組的變換對全部子圖元都有效,QGraphpicsItem莪能夠處理全部子圖元的事件(使用QGraphicsItem::setHandlesChildEvents()),即容許組合圖元處理全部子圖元的事件。 
6.8 圖形圖像的打印 
Qt提供了誇平臺的打印支持,可以使用本地和遠程的打印機,Qt的打印系統甚至支持直接生成PostScript可PDF文件,QPrinter類對打印機進行了抽象,他實際上時支持打印的特殊繪圖設備(QPainteDevice).QPrinter支持多頁和雙面打印,使用QPrinter能夠和繪製自定義的窗口同樣完成打印操做。 
普通打印過程。 
QPrinter printer; 
QPrintDialog *dialog=new QPrintDialog(&printer,this); 
dialog->setWindowTitle(tr("打印文檔")); 
if(dialog->exec()!=QDialog::Accepted)  return ;  建立了打印設備後及時對打印設備的設置,而後就開始打印  QPainter painter; 
painter.begin(&printer); 
for(int page=0;page<numberofPages;++page)  {
  if(page!=lastPage)  printer.newPage(); 
} 
painter.end();  paperRect()獲取紙張尺寸,pageRect()獲取可打印的區域大小 
void MainWindow::print()  { 
QPrinter printer; 
QPrintDialog dialog(&printer,this); 
if(dialog.exec())  { 
QPainter painter(&printer); 
QRect rect=painter.viewport(); 
QSize size=imageWidget->size(); 
size.scale(rect.size(),Qt::KeepAspectRatio); 
painter.setViewport(rect.x(),rect.y(),size.width() ,size.height()); 
painter.setWindow(imageWidget->rect()); 
painter.drawPixmap(0,0,QPixmap::grabWidget(imageWi dget,imageWidget->rect())); 
} 
} 
程序將窗口部件上的俄圖形用grabWidget()函數抓取到QPixmap對象中,而後直接將QPixmap對象繪製到打印機上。  特殊窗口部件的打印  一些特殊窗口部件的繪製功能是由相應的內容管理類進行管理。如QTextEdit和QGraphicsView顯示的內容分別由QTextDocument和QGraphicsScene類管理。對於這些類,他們的打印功能由內容管理類或特定的函數完成。
這些類如圖 
-------------------------------------------------- 
QGraphicsView QGraphicsView::render();
 QSvgWidget QSvgRenderer::render(); 
QTextEdit QTextDocument::print(); 
QTextLayout QTextLayout::draw(); 
QTextLine QTextLine::draw() 
-------------------------------------------------- 
Graphics View框架經過場景QGraphicsScene::render()函數和視圖的QGraphicsView::render()函數結合就能夠完成打印工做。這兩個函數將場景和視圖上的內容所有打印到任意繪圖設備。  場景和視圖繪製函數的差異就在於一個使用場景座標,一個使用視圖座標,QGraphicsScene::render()一般用來繪製沒有變換的場景,如幾何數據,文本文檔,QGraphicsView::render()則用來實現屏幕快照,他默認的行爲是將視口的數據繪製到指定的繪圖所設備。當源區域和目標區域大小不相同時,源區域將會按指定的內容縮放以符合目標區域,縮放比例取決於Qt::AspectRadioMode. 
void MainWindow::print()  { 
QPrinter printer; 
if(QPrintDialog(&printer).exec()==QDialog::Accepte d) 
{ 
QPainter painter(&printer); 
painter.setRenderHint(QPainter::Antialiasing); 
scene->render(&painter); 
} 
} 
用戶能夠將上面的scene->render(&painter)換爲view->render(&painter).
相關文章
相關標籤/搜索