Qt開發技術:圖形視圖框架(一)基本介紹

若該文爲原創文章,轉載請註明原文出處
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/115791408
各位讀者,知識無窮而人力有窮,要麼改需求,要麼找專業人士,要麼本身研究
紅胖子(紅模仿)的博文大全:開發技術集合(包含Qt實用技術、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機、軟硬結合等等)持續更新中…(點擊傳送門)框架

Qt開發專欄:開發技術(點擊傳送門)

上一篇:無
下一篇:敬請期待函數


前話

  使用到Qt的視圖框架。工具


Qt視圖框架介紹

簡介

  圖形視圖框架(The Graphic View Framework)用於管理和與大量定製的二維圖形項目交互,以及用於可視化項目的視圖小部件,支持縮放和旋轉。
  在這裏插入圖片描述佈局

  該框架包括一個事件傳播體系結構,容許對場景中的項目進行精確的雙精度交互。項目能夠處理按鍵事件、鼠標按下、移動、釋放和雙擊事件,還能夠跟蹤鼠標移動。
  圖形視圖使用BSP(Binary Space Partitioning,即二進制空間分區)樹提供很是快讀得項目發現,所以,它能夠實時現實大型場景,即便有數百萬個項目。
  圖形視圖提供了一種基於項目得模型視圖變成方法,多個視圖能夠觀察單個場景,而且場景包含不一樣幾何圖形的項目。性能

場景(The Scene)

  QGraphicsScene提供了圖形視圖場景,場景有以下職責:字體

  • 爲管理大量項目(圖元項目)提供快速界面;(實測同一個區域不能重疊多了,繪製會卡頓)
  • 將事件傳播到每一個項;
  • 管理項目狀態,如選擇和焦點處理;
  • 提供未轉換的渲染功能;主要用於打印;

  該場景用做QGraphicsItem對象的容器。經過調用QGraphicsItem::additem() 將項添加到場景中,而後經過調用多個項發現函數之一來檢索項。QGraphicsItem::items()及其重載返回由點、矩形、多邊形或常規矢量路徑包含或與之相交的全部項。QGraphicsItem::itemAt()返回特定點的最上面的項。全部項目發現功能都按降序堆疊順序返回項目(即第一個返回的項目是最上面的,最後一個項目是最下面的)。優化

QGraphicsScene scene;
QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100))
QTransform transform;;
QGraphicsItem *item = scene.itemAt(50, 50, transform);
// item == rect

  QGraphicsScene的事件傳播體系結構安排將場景事件傳遞到項目,並管理項目之間的傳播。若是場景在某個位置接收到鼠標按下事件,則場景將事件傳遞到該位置的任何項目。
  QGraphicsScene還管理某些項狀態,例如項選擇和焦點。能夠經過調用QGraphicsScene::setSelectionArea(),傳遞任意形狀來選擇場景中的項目。該功函數還可用做QGraphicsView中橡皮擦的選擇區域。要獲取全部當前選定項的列表,請調用QGraphicscene::selecteditems()。QGraphicsScene處理的另外一個狀態是項是否具備鍵盤輸入焦點。能夠經過調用QGraphicScene::setFocusItem()或 QGraphicsItem::setFocus()對項設置焦點,也能夠經過調用QGraphicscene::focusItem()獲取當前焦點項。
  最後,QGraphicScene容許您經過QGraphicScene::render()函數將部分場景渲染到繪製設備中。能夠「打印」部分了解更多有關此內容的信息。動畫

視圖(The View)

  QGraphicsView提供了視圖小部件,它能夠可視化場景的內容。能夠將多個視圖附加到同一場景中,以便在同一數據集中提供多個視口。視圖小部件是一個滾動區域,並提供滾動條用於在大型場景中導航。要啓用OpenGL支持,能夠經過調用QGraphicsView::setViewport()將QGLWidget設置爲視區。spa

QGraphicsScene scene;
myPopulateScene(&scene);
QGraphicsView view(&scene);
view.show();

  在將事件發送到可視化場景以前,視圖從鍵盤和鼠標接收輸入事件,並將其轉換爲場景事件(在適當的狀況下將使用的座標轉換爲場景座標)。
  用轉換矩陣QGraphicsView::transform(),視圖能夠轉換場景的座標系。這容許高級導航功能,如縮放和旋轉。爲了方便起見,qgraphicsView還提供了在視圖和場景座標之間轉換的函數:QGraphicsView::mapToScene()和 QGraphicsView::mapFromScene()。
  在這裏插入圖片描述.net

項目(The Item):圖形元素

QGraphicsItem是場景中圖形項的基類。圖形視圖爲典型形狀提供了幾個標準項,例如矩形(QGraphicsRectItem)、橢圓(QGraphicsEllipsItem)和文本項(QGraphicsTextItem),但在編寫自定義項時,最強大的QGraphicsItem功能可用。除此以外,QGraphicsItem還支持如下功能:

  • 鼠標按下、移動、釋放和雙擊事件,以及鼠標懸停事件、滾輪事件和上下文菜單事件;
  • 鍵盤輸入焦點和按鍵事件;
  • 拖放;
  • 分組,經過父子關係,經過QGraphicsItemGroup;
  • 碰撞檢測;

  項目位於本地座標系中,與QGraphicsView相似,它還提供許多功能,用於在項目和場景之間以及從項目到項目之間映射座標。此外,與QGraphicsView同樣,它可使用矩陣:QGraphicsItem::Transform()轉換其座標系。這對於旋轉和縮放單個項目頗有用。
  項能夠包含其餘項(子項)。父項的轉換由其全部子項繼承。可是,無論一個項的累積轉換如何,它的全部函數(例如,QGraphicsItem::contains()QGraphicsItem::boundingRect()QGraphicsItem::collectsWith() 仍在本地座標中操做。
  QGraphicsItem支持經過QGraphicsItem::shape()函數和QGraphicsItem::collipswith() 進行衝突檢測,這兩個函數都是虛擬函數。經過從QGraphicsItem::shape() 中返回項目的形狀做爲本地座標QPaineterPath,QGraphicsItem將爲您處理全部衝突檢測。可是,若是您但願提供本身的碰撞檢測,則能夠從新實現QGraphicsItem::CollipsWith()
  在這裏插入圖片描述

Qt圖形視圖框架中的類

  這些類爲建立交互式應用程序提供了一個框架。
  在這裏插入圖片描述


圖形視圖座標系

  圖形視圖基於笛卡爾座標系;場景中項目的位置和幾何圖形由兩組數字表示:X座標和Y座標。使用未轉換視圖觀察場景時,場景中的一個單元由屏幕上的一個像素表示。
  注意:因爲圖形視圖使用qt座標系,所以不支持倒Y軸座標系(Y向上增加)。
  圖形視圖中有三個有效的座標系:項目座標、場景座標和視圖座標。爲了簡化實現,圖形視圖提供了方便的功能,容許您在三個座標系之間進行映射。
  渲染時,圖形視圖的場景座標對應於QPainer的邏輯座標,視圖座標與設備座標相同。後續會說明邏輯座標和設備座標之間的關係。
  在這裏插入圖片描述

項目座標

  項目在本身的本地座標系中。它們的座標一般以中心點(0,0)爲中心,這也是全部變換的中心。項目座標系中的幾何基元一般稱爲項目點、項目線或項目矩形。
  在建立自定義項時,只須要擔憂項座標;QGraphicsScene和QGraphicsView將爲您執行全部轉換。這使得實現自定義項很是容易。例如,若是收到一個鼠標按下或拖動輸入事件,則事件位置在項目座標中給出。QGraphicsItem::contains()虛函數,若是某個點在項中,則返回true,不然返回false,在項座標中接受一個點參數。相似地,項的邊界矩形和形狀位於項座標中。
  在項目的位置是項目中心點在其父座標系中的座標;有時稱爲父座標。在這個意義上,場景被視爲全部無父項的「父項」。頂層項目的位置在場景座標中。
  子座標是相對於父座標的。若是子座標未轉換,則子座標和父座標之間的差別與父座標中項目之間的距離相同。例如:若是未轉換的子項精肯定位在其父項的中心點,則兩個項的座標系將相同。可是,若是子對象的位置是(10,0),子對象的(0,10)點將對應於其父對象的(10,10)點。
  由於項的位置和轉換是相對於父項的,因此子項的座標不受父項的轉換的影響,儘管父項的轉換隱式轉換子項。在上面的例子中,即便父對象被旋轉和縮放,子對象的(0,10)點仍然對應於父對象的(10,10)點。可是,相對於場景,子對象將遵循父對象的變換和位置。若是縮放父對象(2x,2x),子對象的位置將位於場景座標(20,0),其(10,0)點將對應於場景上的點(40,0)。
  因爲QGraphicsItem::pos()是少數例外之一,所以QGraphicsItem的函數在項座標中操做,而不考慮項或其任何父項的轉換。例如,項目的邊界矩形(即QGraphicsItem::boundingRect())老是在項目座標中給出。

場景座標

  場景表示其全部項的基礎座標系。場景座標系描述了每一個頂層項目的位置,也構成了從視圖傳遞到場景的全部場景事件的基礎。場景中的每一個項目都有一個場景位置和邊界矩形(QGraphicsItem::scenePos()和  QGraphicsItem::sceneBoundingRect()),除了其本地項pos和邊界矩形以外。場景位置描述了項目在場景座標中的位置,其場景邊界矩形構成了QGraphicsScene如何肯定場景的哪些區域已更改的基礎。場景中的更改經過QGraphicsScene::changed()信號進行通訊,參數是場景矩形的列表。

視圖座標

  視圖座標是小部件的座標。視圖座標中的每一個單元對應一個像素。這個座標系的特殊之處在於它相對於小部件或視區,而且不受觀察到的場景的影響。QGraphicsView的視區的左上角始終是(0,0),右下角始終是(視區寬度,視區高度)。全部鼠標事件和拖放事件最初都做爲視圖座標接收,您須要將這些座標映射到場景,以便與項目交互。

座標映射

**  在處理場景中的項目時,一般能夠將座標和任意形狀從場景映射到項目、從項目映射到項目或從視圖映射到場景。例如,在QGraphicsView的視區中單擊鼠標時,能夠經過調用QGraphicsView::mapToScene(),而後調用QGraphicsScene::ItemAt()來詢問場景光標下的項目。若是要知道某個項在視區中的位置,能夠對該項調用QGraphicsItem::MapToScene(),而後在視圖上調用QGraphicsView::MapFromSecene()。最後,若是要查找視圖橢圓中的項目,能夠將QPaineterPath傳遞給mapToScene(),而後將映射的路徑傳遞給QGraphicScene::items()。
  經過調用QGraphicsItem::MapToScene()和QGraphicsItem::mapFromScene(),能夠將座標和形狀映射到項的場景或從中映射。還能夠經過調用QGraphicsItem::mapTopParent()和qgraphicsItem::mapFromParent()映射到項的父項,或者經過調用QGraphicsItem::MapToItem()和QGraphicsItem::mapFromItem()在項之間映射。全部映射函數均可以映射點、矩形、多邊形和路徑。
  視圖中有相同的映射函數,可用於映射到場景或從場景映射到場景。QGraphicsView::mapFromSecene()和QGraphicsView::mapToScene()。要從視圖映射到項目,首先映射到場景,而後從場景映射到項目。**


關鍵特徵

縮放和旋轉

  QGraphicsView支持與QPainer經過QGraphicsView::setMatrix()進行的相同的仿射轉換。經過對視圖應用轉換,您能夠輕鬆地添加對常見導航功能(如縮放和旋轉)的支持。
如下是如何在QGraphicsView子類中實現縮放和旋轉插槽的示例:

class View : public QGraphicsView
{
  Q_OBJECT
  ...
public slots:
  void zoomIn() { scale(1.2, 1.2); }
  void zoomOut() { scale(1 / 1.2, 1 / 1.2); }
  void rotateLeft() { rotate(-10); }
  void rotateRight() { rotate(10); }
  ...
};

  槽函數能夠鏈接到啓用自動重複的QToolButtons。
  轉換視圖時,QGraphicsView保持視圖中心對齊。
  有關如何實現基本縮放功能的代碼,後續會有示例描述。

項目組

  經過使一個項目成爲另外一個項目的子項目,您能夠實現項目分組最基本的特性:

  • 項目將一塊兒移動
  • 全部轉換都從父項目傳播到子項目。

  此外,QGraphicsItemGroup是一個特殊的項,它將子事件處理與用於向組中添加和刪除項的有用接口結合在一塊兒。將項添加到QGraphicsItemGroup將保留該項的原始位置和轉換,而一般從新設置項將致使子項相對於其新父項從新定位自身。爲了方便起見,能夠經過調用QGraphicScene::CreateItemGroup()經過場景建立QGraphicsItemGroups。

小部件和佈局

Qt4.4經過QGraphicsWidget引入了對幾何和佈局感知項的支持。這個特殊的基項相似於QWidget,但與QWidget不一樣,它不是從QPaintDevice繼承的,而是從QGraphicsItem繼承的。這容許您編寫帶有事件、信號和槽、大小提示和策略的完整小部件,還能夠經過QGraphicsLinearLayout和QGraphicsGridLayout在佈局中管理小部件的幾何圖形。

QGraphicsWidget

  基於QGraphicsItem的功能和精簡的佔地面積,QGraphicsWidget提供了兩個方面的最佳功能:QWidget的額外功能,例如樣式、字體、調色板、佈局方向及其幾何圖形,以及QGraphicsItem的分辨率獨立性和轉換支持。由於圖形視圖使用實座標而不是整數,因此QGraphicsWidget的幾何函數也在QRectF和QPointF上運行。這也適用於框架矩形、邊距和間距。例如,對於QGraphicsWidget,指定內容頁邊距(0.五、0.五、0.五、0.5)並很多見。您能夠建立子窗口和「頂級」窗口;在某些狀況下,您如今能夠爲高級MDI應用程序使用圖形視圖。
  一些QWidget的屬性是受支持的,包括窗口標誌和屬性,但不是所有。參考QGraphicsWidget的類文檔,以全面瞭解什麼是受支持的,什麼是不受支持的。例如,能夠經過將Qt::window標誌傳遞給QGraphicsWidget的構造函數來建立裝飾窗口,但圖形視圖當前不支持MacOs上常見的Qt::Sheet和Qt:: Drawer標誌。

QGraphicsLayout

  QGraphicsLayout是專門爲QGraphicsWidget設計的第二代佈局框架的一部分。它的API與QLayout很是類似。您能夠在QGraphicsLinearLayout和QGraphicsGridLayout中管理小部件和子佈局。您還能夠經過本身對QGraphicsLayout子類化來輕鬆地編寫本身的佈局,或者經過編寫QGraphicsLayoutItem的適配器子類,將本身的QGraphicsItem項添加到佈局中。

嵌入式小部件支持

  圖形視圖爲在場景中嵌入任何小部件提供無縫支持。您能夠嵌入簡單的小部件,如QLineEdit或QPushButton,複雜的小部件,如QTabWidget,甚至完整的主窗口。要將小部件嵌入到場景中,只需調用QGraphicScene::AddWidget(),或建立QGraphicsProxyWidget實例手動嵌入小部件。
  經過QGraphicsProxyWidget,圖形視圖可以深刻集成客戶端小部件的功能,包括其光標、工具提示、鼠標、平板電腦和鍵盤事件、子小部件、動畫、彈出窗口(如QComboBox或QCompeter),以及小部件的輸入焦點和激活。QGraphicsProxyWidget甚至集成了嵌入式小部件的選項卡順序,這樣您就能夠在嵌入式小部件中插入和取出選項卡。甚至能夠將新的QGraphicsView嵌入到場景中,以提供複雜的嵌套場景。
  當轉換嵌入的小部件時,圖形視圖確保小部件獨立地轉換分辨率,容許字體和樣式在放大時保持清晰。(請注意,分辨率獨立性的效果取決於樣式。)


性能

浮點指令

  爲了準確、快速地對項目應用轉換和效果,在假設用戶的硬件可以爲浮點指令提供合理性能的前提下,構建了圖形視圖。
  許多工做站和臺式計算機都配備了適當的硬件來加速這種計算,可是一些嵌入式設備可能只提供庫來處理數學運算或模擬軟件中的浮點指令。
  所以,某些類型的影響在某些設備上可能比預期的慢。能夠經過在其餘區域進行優化來補償這種性能損失;例如,使用OpenGL渲染場景。可是,若是這些優化還依賴於浮點硬件的存在,那麼它們自己可能會致使性能下降。


上一篇:無
下一篇:敬請期待


若該文爲原創文章,轉載請註明原文出處
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/115791408

相關文章
相關標籤/搜索