Graphics View Framework
互動式 2D 圖形的 Graphics View 框架概述,自 Qt4.2 中引入了 Graphics View,以取代其前身 QCanvas,Graphics View 提供了一個用于管理和互動大量的可定制的 2D 圖形項與用于可視化這些項的 View 小部件的 surface(曲面),并提供縮放(zooming)和旋轉(rotation)功能支持,
該框架包括事件傳播體系結構(an event propagation architecture),該體系結構允許對場景中的專案進行精確的雙精度互動功能,圖元可以被如下操作處理:按鍵事件,滑鼠按下,移動,釋放和雙擊事件,它們還可以跟蹤滑鼠的移動,
Graphics View 使用 BSP(Binary Space Partitioning,二進制空間磁區)樹提供了非常快速的圖元發現功能,因此,它可以實時可視化大型場景(甚至可以包含數百萬個圖元),下面列出 Graphics View Framework 的常用模塊:
graph LR subgraph Graphics W[QtCore.QObject] --> F(QtWidgets.QGraphicsObject) F --> S(QtWidgets.QGraphicsTextItem) end subgraph View BB[QtWidgets.QGraphicsLayoutItem] --> AA A[QtGui.QPaintDevice] --> B(QtWidgets.QWidget) B --> C(QtWidgets.QFrame) WW --> FF(QtWidgets.QGraphicsItemGroup) WW -->3F(QtWidgets.QGraphicsLineItem) WW --> 4F(QtWidgets.QGraphicsPixmapItem) W --> B WW --> F(QtWidgets.QGraphicsObject) F --> AA(QtWidgets.QGraphicsWidget) end subgraph Graphics AA --> AAA(QtCharts.QChart) C --> D(QtWidgets.QAbstractScrollArea) D -->E(QtWidgets.QGraphicsView) W --> U(QtWidgets.QGraphicsScene) end subgraph Shape WW[QtWidgets.QGraphicsItem] --> EE(QtWidgets.QAbstractGraphicsShapeItem) EE --> QQ(QtWidgets.QGraphicsEllipseItem) EE --> 3Q(QtWidgets.QGraphicsPathItem) EE --> 4Q(QtWidgets.QGraphicsPolygonItem) EE --> 5Q(QtWidgets.QGraphicsRectItem) EE --> 6Q(QtWidgets.QGraphicsSimpleTextItem) end1 The Graphics View Architecture
Graphics View 提供了一種基于專案(item-based)的方法來進行模型-視圖編程(model-view programming),非常類似于 InterView 的便利類 QTableView,QTreeView 和 QListView,多個視圖可以觀察單個場景,并且該場景包含各種幾何形狀的圖元專案,
1.1 The Scene
QtWidgets.QGraphicsScene 提供了 Graphics View 場景,QGraphicsScene 類提供了一個用于管理大量 2D 圖形專案的容器(surface),
場景具有如下功能:
- 提供用于管理大量圖元專案的快速界面
- 將事件傳播到每個圖元專案
- 管理圖元專案狀態,例如選擇和焦點處理
- 提供未被轉換的渲染功能;主要用于印刷
場景用作 QtWidgets.QGraphicsItem 物件的容器,它與 QtWidgets.QGraphicsView 一起用于可視化 2D 曲面上(2D surface)的圖形專案,例如線條,矩形,文本,甚至是自定義專案,通過呼叫 addItem() 將圖元專案添加到場景中,然后通過呼叫許多專案查找功能之一來檢索專案,
請注意,QGraphicsScene 沒有自己的視覺外觀,它只管理圖元專案,您需要創建一個 QGraphicsView 小部件以可視化場景,
要將專案添加到場景,首先需要構造一個 QGraphicsScene 物件,然后,您有兩個選擇:通過呼叫 addItem() 添加現有的 QGraphicsItem 物件,或者可以呼叫下列便捷函式之一 addEllipse(),addLine(),addPath(),addPixmap(),addPolygon(),addRect() 或 addText(),它們都回傳一個指向新添加專案的指標,使用這些函式添加的圖元的維度是相對于圖元(item)的坐標系的,并且圖元的位置在場景中被初始化為 \((0,0)\),
您可以使用 QGraphicsView 可視化場景,當場景發生變化時(例如,當某項移動或變換時),QGraphicsScene 發出 change() 信號,要洗掉專案,請呼叫 removeItem(),
QGraphicsScene 使用索引演算法來有效地管理專案的位置,默認情況下,使用 BSP(二進制空間磁區)樹;一種適用于大型場景的演算法,其中大多數圖元保持靜止(即不要四處移動),您可以選擇通過呼叫 setItemIndexMethod() 禁用此索引,
通過呼叫 setSceneRect() 設定場景的邊界矩形,可以將圖元專案放置在場景中的任何位置,默認情況下,場景的大小不受限制,場景 rect 僅用于內部簿記,維護場景的圖元專案索引,如果未設定場景矩形,則 QGraphicsScene 將使用 itemsBoundingRect() 回傳的所有專案的邊界區域作為場景矩形,但是,itemsBoundingRect() 是一個相對耗時的函式,因為它通過收集場景中每個專案的位置資訊進行操作,因此,在大型場景上操作時,應始終設定場景 rect,
QGraphicsScene 的最大優勢之一就是能夠有效確定圖元的位置,即使場景中有數百萬個專案,items() 函式也可以在幾毫秒內確定專案的位置,items() 有多個多載:一個多載在某個位置查找專案,一個多載在多邊形或矩形內部或與之相交,等等,回傳的專案串列按堆疊順序排序,最高的專案是串列中的第一專案,為了方便起見,還有一個 itemAt() 函式可在給定位置回傳最上面的專案,
QGraphicsScene 還管理某些圖元專案狀態,例如圖元專案選擇和焦點,要選擇專案,請呼叫 setSelectionArea()(傳遞任意形狀來選擇場景中的專案),并要清除當前選擇,請呼叫clearSelection(),呼叫 selectedItems() 以獲取所有選定項的串列,
函式 setSelectionArea() 還用作 QGraphicsView 中橡皮筋選擇的基礎,要獲取所有當前選定專案的串列,請呼叫 selectedItems() ,QGraphicsScene處理的另一個狀態是專案是否具有鍵盤輸入焦點,您可以通過呼叫 setFocusItem() 或 setFocus() 來設定焦點,或者通過呼叫 focusItem() 來獲取當前焦點,
場景的呼叫方法:
QGraphicsScene(sceneRect[, parent=None])
QGraphicsScene(x, y, width, height[, parent=None])
QGraphicsScene 的另一個職責是傳播來自 QGraphicsView 的事件,要將事件發送到場景,您可以構造一個繼承 QEvent 的事件,然后使用 sendEvent() 進行發送,event() 負責將事件調度到各個圖元專案,一些常見事件由便利事件處理程式處理,例如,按鍵事件由 keyPressEvent() 處理,滑鼠按鍵事件由 mousePressEvent() 處理,
按鍵事件將傳遞到焦點圖元專案,要設定焦點圖元專案,可以呼叫 setFocusItem(),傳遞接受焦點的圖元專案,或者該專案本身可以呼叫 setFocus(), 呼叫 focusItem() 以獲取當前的焦點專案,為了與小部件兼容,場景還保留其自己的焦點資訊,默認情況下,場景沒有焦點,并且所有按鍵事件都將被丟棄,如果呼叫 setFocus() 或場景中的某個專案獲得焦點,則場景將自動獲得焦點,如果場景具有焦點,則 hasFocus() 將回傳 true,并將按鍵事件轉發到焦點項(如果有),如果場景失去焦點(例如,有人在某個專案具有焦點時呼叫 clearFocus()),則場景將保留其專案焦點資訊,并且一旦場景重新獲得焦點,它將確保最后一個焦點專案重新獲得焦點,
對于滑鼠懸停效果,QGraphicsScene 調度懸停事件,如果某個圖元專案接受懸停事件(請參見acceptHoverEvents()),則當滑鼠進入其區域時,它將收到 GraphicsSceneHoverEnter 事件,當滑鼠繼續在專案區域內移動時, QGraphicsScene 將向其發送 GraphicsSceneHoverMove 事件,當滑鼠離開該專案的區域時,該專案將收到 GraphicsSceneHoverLeave 事件,
所有滑鼠事件都會傳遞到當前的滑鼠采集器專案,如果一個專案接受滑鼠事件(請參見 acceptedMouseButtons() 并且接受滑鼠按下,則它將成為場景的滑鼠捕獲器,當沒有其他滑鼠按鈕被按下時,它會一直停留在滑鼠抓取器上,直到釋放滑鼠為止,您可以呼叫 mouseGrabberItem() 來確定當前正在抓住滑鼠的圖元專案,
最后,QGraphicsScene 允許您通過 render() 函式將場景的一部分渲染到繪制設備中,
1.2 The View
QGraphicsView 類提供了一個用于顯示 QGraphicsScene 的內容小部件,QGraphicsView 在可滾動視口(viewport)中可視化 QGraphicsScene 的內容,
QGraphicsView 提供了視圖小部件,可將場景的內容可視化,您可以將多個視圖附加到同一場景,以在同一資料集中提供多個視口,視圖視窗小部件是一個滾動區域,并提供用于在大型場景中導航的滾動條,要啟用 OpenGL 支持,可以通過呼叫 setViewport() 將 QOpenGLWidget 設定為視口,
視圖從鍵盤和滑鼠接收輸入事件,然后將其轉換為場景事件(在適當的情況下將其轉換為場景坐標),然后再將事件發送到可視化場景,
使用其變換矩陣 transform(),視圖可以變換場景的坐標系,這允許高級導航功能,例如縮放和旋轉,為了方便起見,QGraphicsView 還提供了用于在視圖和場景坐標之間進行轉換的函式:mapToScene() 和 mapFromScene(),
QtWidgets.QGraphicsView 在可滾動 viewport 中可視化 QtWidgets.QGraphicsScene 的內容,
為了使場景可視化,首先要構造一個 QtWidgets.QGraphicsView 物件,然后將要可視化的場景的地址傳遞給 QtWidgets.QGraphicsView 的建構式,另外,您可以呼叫 setScene() 在以后設定場景,呼叫 show() 后,默認情況下,視圖將滾動到場景的中心并顯示此時可見的所有圖元專案, 例如:
scene = QGraphicsScene()
scene.addText("Hello, world!")
# 等價于 QGraphicsView(scene)
view = QGraphicsView()
view.setScene(scene)
view.show()
您可以使用滾動潭訓呼叫 centerOn() 顯式滾動到場景中的任何位置,通過將一個點傳遞給 centerOn(),QGraphicsView 將滾動其視口以確保該點在視圖中居中,同時提供了用于滾動到 QGraphicsItem 的多載,在這種情況下,QGraphicsView 將看到專案的中心在視圖中居中,如果只需要確保某個區域可見(但不必居中),則可以呼叫 sureVisible(),
QGraphicsView 可用于可視化整個場景或其中的一部分,默認情況下,第一次顯示視圖時,會自動檢測到可視化區域(通過呼叫 itemsBoundingRect()),要自己設定可視化區域矩形,可以呼叫 setSceneRect(),這將適當地調整滾動條的范圍,請注意,盡管場景支持幾乎不受限制的大小,但滾動條的范圍永遠不會超出整數 (INT_MIN, INT_MAX) 的范圍,
QGraphicsScene 還管理某些圖元專案狀態,例如圖元專案選擇和焦點,您可以通過呼叫 setSelectionArea() 傳遞任意形狀來選擇場景中的專案,此函式還用作 QGraphicsView 中橡皮筋選擇的基礎,要獲取所有當前選定專案的串列,請呼叫 selectedItems(), QGraphicsScene 處理的另一個狀態是專案是否具有鍵盤輸入焦點,您可以通過呼叫 setFocusItem() 或 setFocus() 來設定焦點,或者通過呼叫 focusItem() 來獲取當前焦點,
QGraphicsView 通過呼叫 render() 可視化場景,默認情況下,使用常規 QPainter 并使用默認渲染提示將專案繪制到視口上,若要更改繪畫專案時 QGraphicsView 傳遞給 QPainter 的默認渲染提示,可以呼叫setRenderHints(),
默認情況下,QGraphicsView 為視口視窗小部件提供常規 QWidget,您可以通過呼叫 viewport() 來訪問此小部件,也可以通過呼叫 setViewport() 來替換它,
要使用 OpenGL 進行渲染,只需呼叫 setViewport(新的 QOpenGLWidget),QGraphicsView 擁有視口小部件的所有權,
QGraphicsView 使用 QTransform 支持仿射變換,最常見的兩種轉換是 scaling,用于實作縮放(zooming)和旋轉(rotation),QGraphicsView 在轉換程序中保持視圖中心不變,由于場景對齊(setAligment()),平移視圖將不會產生視覺影響,您可以將矩陣傳遞給 setTransform(),也可以呼叫便捷函式之一 rotate(),scale(),translate() 或 shear(),
您可以使用滑鼠和鍵盤與場景中的專案進行互動,QGraphicsView 將滑鼠和鍵事件轉換為場景事件(繼承 QGraphicsSceneEvent 的事件),并將其轉發到可視化場景,最后,處理事件并對事件做出反應的是獨立專案,例如,如果單擊一個可選擇的專案,則該專案通常會讓場景知道它已被選中,并且它還將重繪自身以顯示選擇矩形,類似地,如果您單擊并拖動滑鼠以移動可移動項,則它是處理滑鼠移動并自行移動的項,默認情況下,圖形專案互動處于啟用狀態,您可以觸發呼叫,
您還可以通過創建 QGraphicsView 的子類并重新實作滑鼠和鍵事件處理程式來提供自己的自定義場景互動,
為了簡化您如何以編程方式與視圖中的專案進行互動,QGraphicsView 提供了映射函式 mapToScene() 和 mapFromScene() 以及專案訪問器 items() 和 itemAt(),這些功能允許您在視圖坐標和場景坐標之間映射點,矩形,多邊形和路徑,并使用視圖坐標在場景中查找專案,
QtWidgets.QGraphicsView(scene[, parent=None]):
parent:QWidgetscene:QGraphicsScene
1.3 The Item
QGraphicsItem 是場景中圖形項的基類,Graphics View 為典型形狀提供了幾個標準項,例如矩形(QGraphicsRectItem),橢圓(QGraphicsEllipseItem)和文本項(QGraphicsTextItem),但時,最強大的是 QGraphicsItem 可以撰寫自定義項,除此之外,QGraphicsItem 支持以下功能:
- 滑鼠按下,移動,釋放和雙擊事件,以及滑鼠懸停事件,滾輪事件和背景關系選單事件,
- 鍵盤輸入焦點和按鍵事件
- 拖放
- 通過 parent-child 關系以及 QGraphicsItemGroup 進行分組
- 碰撞檢測(Collision detection)
圖元專案位于本地坐標系(local coordinate system)中,就像 QGraphicsView 一樣,它還提供了許多功能,用于在專案與場景之間以及專案與專案之間映射坐標,而且,像 QGraphicsView 一樣,它可以使用 matrix:transform() 變換其坐標系,這對于旋轉和縮放單個專案很有用,
項可以包含其他項(子項),父項的轉換由其所有子項繼承,不過,不管某項的累積轉換如何,它的所有功能(例如,contains(), boundingRect(), QGraphicsItem::collidesWith())都仍在本地坐標下運行,
QGraphicsItem 通過 shape() 函式和 QGraphicsItem::collidesWith() 這兩個虛擬函式都支持沖突檢測,通過從 shape() 回傳專案的形狀作為區域坐標 QPainterPath,QGraphicsItem 將為您處理所有碰撞檢測,但是,如果要提供自己的沖突檢測,則可以重新實作 QGraphicsItem::collidesWith(),
更多內容見:QtWidgets.QGraphicsItem,
QtWidgets.QGraphicsItem 類是 QtWidgets.QGraphicsScene 中所有圖形項的基類,為了方便描述,將 QtWidgets.QGraphicsItem 實體命名為圖元,QtWidgets.QGraphicsItem 為撰寫您自己的自定義圖元項提供了一個輕量級的基礎,它包括定義圖元項的幾何形狀(geometry),碰撞檢測(collision detection),且有繪畫實作以及通過事件處理程式進行的圖元項互動,
為方便起見,Qt為最常見的形狀提供了一組標準圖形項:
QGraphicsEllipseItem:提供 ellipse itemQGraphicsLineItem:提供 line itemQGraphicsPathItem:提供任意 path itemQGraphicsPixmapItem:提供 pixmap itemQGraphicsPolygonItem:提供 polygon itemQGraphicsRectItem:提供 rectangular itemQGraphicsSimpleTextItem:提供簡單 text label itemQGraphicsTextItem:提供高級 text browser item
圖元專案的所有幾何資訊均基于其本地坐標系(Local Coordinate System)[1],該圖元項的位置 pos() 是唯一在本地坐標中不起作用的函式,因為它在父坐標中回傳一個位置,
您可以通過呼叫 setVisible() 設定圖元專案是否應可見(即繪制和接受事件),隱藏圖元專案也會隱藏其子項,同樣,您可以通過呼叫 setEnabled() 啟用或禁用圖元專案,
如果禁用某個圖元專案,則其所有子項也將被禁用,默認情況下,圖元專案既可見又啟用,若要切換是否選擇圖元專案,請首先通過設定 ItemIsSelectable 標志啟用選擇,然后呼叫 setSelected(),通常,由于用戶互動,場景(scene)會切換選擇,
要撰寫自定義的圖元專案,首先創建 QGraphicsItem 的子類,然后實作其兩個純虛擬公共函式:boundingRect() 回傳該圖元專案所繪制區域的估計值,paint() 實作實際繪圖(the actual painting),例如:
class SimpleItem(QtWidgets.QGraphicsItem):
def boundingRect(self):
penWidth = 1.0
return QtCore.QRectF(-10 - penWidth / 2, -10 - penWidth / 2,
20 + penWidth, 20 + penWidth)
def paint(self, painter, option, widget):
painter.drawRoundedRect(-10, -10, 20, 20, 5, 5)
boundingRect() 函式有許多不同的用途,QtWidgets.QGraphicsScene 的專案索引基于 boundingRect(),并且 QtWidgets.QGraphicsView 將其用于剔除不可見的專案以及確定繪制重疊專案時需要重新組合的區域,此外,QtWidgets.QGraphicsItem 的碰撞檢測機制使用 boundingRect() 提供有效的截止點(cut-off),collidesWithItem() 中的細粒度碰撞演算法基于呼叫 shape() 的方法,該方法會回傳圖元形狀的精確輪廓作為QtGui.QPainterPath,
QtWidgets.QGraphicsScene 期望所有圖元專案的 boundingRect() 和 shape() 保持不變,除非得到通知,如果您想以任何方式更改圖元的幾何形狀,則必須首先呼叫 prepareGeometryChange() 以允許 QtWidgets.QGraphicsScene 更新其簿記(bookkeeping),
碰撞檢測可以通過兩種方式完成:
- 重新實作
shape()以為您的圖元回傳準確的形狀,并依靠collidesWithItem()的默認實作進行形狀與形狀的交點(shape-shape intersection),如果形狀復雜,這可能代價會非常高, - 重新實作
collidesWithItem()以提供您自己的自定義圖元專案和形狀碰撞演算法,
可以呼叫 contains() 函式來確定圖元專案是否包含一個點,該函式也可以通過圖元項重新實作,contains() 的默認行為是基于呼叫 shape() 的,
圖元專案可以包含其他圖元專案,也可以被包含在其他圖元專案中,所有圖元專案都可以有一個父圖元專案和一列子專案,除非該圖元專案沒有父物件,否則它的位置是父物件的坐標(即父物件的本地坐標),父項將其位置及其變換傳播給所有子項,
1.3.1 Transformations
QtWidgets.QGraphicsItem 除了提供其基本位置 pos() 外,還支持投影變換(projective transformations),有幾種更改圖元專案變換的方法,對于簡單轉換,可以呼叫便捷函式 setRotation() 或setScale(),也可以將任何變換矩陣傳遞給 setTransform(),對于高級轉換控制,您還可以通過呼叫 setTransformations() 來設定多個組合轉換,
圖元項變換從父項到子項累積,因此,如果父項和子項都旋轉 90 度,則子項的總轉換將為 180 度,同樣,如果專案的父項縮放到其原始大小的 2 倍(2x),則其子項也將擴大兩倍,圖元項的變形不會影響其自身的區域幾何關系( local geometry);所有幾何函式(例如,contains(),update() 和所有映射函式)仍在區域坐標(local coordinates)下運行,為方便起見,QtWidgets.QGraphicsItem 提供了一個函式 SceneTransform()(它回傳該項的總變換矩陣(包括其位置以及所有父項的位置和變換))和 scenePos()(該函式回傳其在場景坐標中的位置), 要重置圖元的矩陣,請呼叫 resetTransform(),
某些轉換操作根據其應用順序產生不同的結果,例如,如果縮放轉換然后旋轉,則可能會得到與首先旋轉轉換不同的結果,但是,您在 QtWidgets.QGraphicsItem 上設定轉換屬性的順序不會影響最終的轉換,QtWidgets.QGraphicsItem 始終以固定的定義順序應用屬性:
The item’s base transform is applied ( transform() )
The item’s transformations list is applied in order ( transformations() )
The item is rotated relative to its transform origin point ( rotation() , transformOriginPoint() )
The item is scaled relative to its transform origin point ( scale() , transformOriginPoint() )
1.3.2 Painting
QtWidgets.QGraphicsView 呼叫 paint() 函式來繪制圖元專案的內容,該圖元專案沒有背景或沒有默認填充值;該圖元專案后面的任何內容都會在此功能中未明確繪制的所有區域中 shine,您可以呼叫 update() 安排重新繪制,可以選擇傳遞需要重新繪制的矩形,根據圖元專案是否在視圖中可見,該專案可能會或可能不會重新粉刷(repaint),QtWidgets.QGraphicsItem 中沒有等效于 repaint() 的函式,
圖元專案是按視圖繪制的,從父項開始,然后是子項,按升序排列,您可以通過呼叫 setZValue() 設定圖元的堆疊順序,并通過呼叫 zValue() 對其進行測驗,其中,在 z 值高的圖元之前先繪制 z 值低的圖元,堆疊順序適用于同級圖元;父項總是在子項前被繪制,
1.3.3 Sorting
所有圖元專案均按定義的穩定順序繪制,并且此相同的順序決定了當您單擊場景時哪些專案將首先接識訓鼠輸入,通常,您不必擔心排序,因為專案遵循“自然順序”,遵循場景的邏輯結構,
某個圖元專案的子項堆疊在父項的頂部,而同級項則按照插入順序(即,它們被添加到場景或添加到同一父項的順序)堆疊,如果您添加專案 A,然后添加 B,則 B 將位于 A 的頂部,如果您添加 C,則專案的堆疊順序將是 A,然后是 B,然后是 C,
對于高級用戶,有一些方法可以更改專案的排序方式:
- 您可以在一個圖元專案上呼叫
setZValue(),以將其顯式堆疊在其他同級專案之上或之下,項的默認 Z 值為 0,具有相同 Z 值的項按插入順序堆疊, - 您可以呼叫
stackBefore()重新排序子級串列,這將直接修改插入順序, - 您可以設定
ItemStacksBehindParent標志以將子項堆疊在其父項之后,
兩個同級圖元的堆疊順序也計入每個圖元的子代圖元和后代圖元,因此,如果一項在另一項之上,則其所有子項也將在另一項所有子項之上,
1.3.4 Events
QtWidgets.QGraphicsItem 通過虛擬函式 sceneEvent() 從 QtWidgets.QGraphicsScene 接收事件,此函式將最常見的事件分配給一組便捷事件處理程式:
contextMenuEvent()handles context menu eventsfocusInEvent()andfocusOutEvent()handle focus in and out eventshoverEnterEvent(),hoverMoveEvent(), andhoverLeaveEvent()handles hover enter, move and leave eventsinputMethodEvent()handles input events, for accessibility supportkeyPressEvent()andkeyReleaseEvent()handle key press and release eventsmousePressEvent(),mouseMoveEvent(),mouseReleaseEvent(), andmouseDoubleClickEvent()handles mouse press, move, release, click and doubleclick events
您可以通過安裝事件過濾器(event filters)來過濾任何其他圖元專案的事件,此功能與 Qt 的常規事件過濾器(請參閱 installEventFilter())分開,后者僅適用于 QObject 的子類,在通過呼叫 installSceneEventFilter() 將專案安裝為另一個專案的事件過濾器之后,虛擬函式 sceneEventFilter() 會接收到過濾后的事件,您可以通過呼叫 removeSceneEventFilter() 來洗掉專案事件過濾器,
1.3.5 Custom Data
有時,將自定義資料注冊到某個圖元專案(自定義圖元專案或標準圖元專案)很有用,您可以在任何圖元專案上呼叫 setData(),以使用鍵值對(鍵為整數,并且值為 QVariant)將資料存盤在其中,要從專案中獲取自定義資料,請呼叫 data(),Qt 本身完全沒有涉及此功能,
1.3.6 QtWidgets.QGraphicsItem 的使用
class QGraphicsItem([parent=None]) 使用給定的父項構造一個 QtWidgets.QGraphicsItem,它不會修改 parent() 回傳的父物件,
如果 parent 是 None,你可以通過呼叫 addItem() 將圖元專案添加到場景中,該圖元專案將成為頂級圖元專案(top-level item),
QtWidgets.QGraphicsItem.GraphicsItemFlag:列舉描述了可以在圖元專案上設定的不同標志,以切換圖元專案行為中的不同功能,
| 常量 | 描述 |
|---|---|
QGraphicsItem.ItemIsMovable |
該專案支持使用滑鼠進行互動式移動,通過單擊該專案然后拖動,該專案將與滑鼠游標一起移動,如果該專案有孩子,則所有孩子也將移動,如果專案是選擇的一部分,則所有選擇的專案也會移動,通過 QtWidgets.QGraphicsItem 的滑鼠事件處理程式的基本實作,可以方便地提供此功能, |
QGraphicsItem.ItemIsSelectable |
該專案支持選擇,啟用此功能將使 setSelected() 可以切換圖元專案的選擇,通過呼叫 setSelectionArea(),單擊某項或在 QtWidgets.QGraphicsView 中使用橡皮筋選擇,它還將使該項自動被選擇, |
QGraphicsItem.ItemIsFocusable |
該專案支持鍵盤輸入焦點(即它是一個輸入專案),啟用此標志將允許該專案接受焦點,這再次允許將鍵事件傳遞到 keyPressEvent() 和 keyReleaseEvent(), |
QGraphicsItem.ItemClipsToShape |
圖元會剪裁成自己的形狀,該專案無法在其形狀之外繪制或接識訓鼠,平板電腦,拖放或懸停事件,默認情況下禁用,此行為由 drawItems() 或 drawItems() 強制執行,這個標志是在 Qt 4.3 中引入的, |
QGraphicsItem.ItemClipsChildrenToShape |
該項將其所有后代的繪畫剪裁成自己的形狀,此項的直接或間接子項不能超出該專案的形狀,默認情況下,此標志為禁用狀態,孩子們可以在任何地方畫畫,此行為由 drawItems() 或 drawItems() 強制執行, 這個標志是在 Qt 4.3 中引入的, |
更多 flags 見:QGraphicsItem,
1.3.7 QtWidgets.QGraphicsItem.boundingRect()
回傳 QRectF,這個純虛函式將圖元專案的外部邊界定義為矩形;所有繪畫都必須限制在圖元專案的邊界區域內,QtWidgets.QGraphicsView 使用它來確定該圖元專案是否需要重繪,盡管圖元專案的形狀可以是任意的,但邊界矩形始終為矩形,并且不受圖元專案變換的影響,
如果要更改圖元專案的邊界矩形,必須首先呼叫 prepareGeometryChange(),這會通知場景即將發生的更改,以便可以更新其圖元專案幾何索引;否則,場景將不會意識到該圖元的新幾何形狀,并且結果是不確定的(通常,渲染工件( rendering artifacts)保留在視圖(view)中),
重新實作此功能,以使 QtWidgets.QGraphicsView 決定需要重繪視窗小部件的哪些部分(如果有),注意:對于繪制輪廓/筆觸的形狀,重要的是在邊界矩形中包括筆寬的一半,但是,沒有必要補償抗鋸齒,
例子:
def boundingRect(self):
penWidth = 1.0
return QtCore.QRectF(-radius - penWidth / 2, -radius - penWidth / 2,
diameter + penWidth, diameter + penWidth)
更多精彩參考我的另一篇博文:Qt 手冊,
本地坐標系是以物體自身位置作為原點,表示物體間相對位置和方向,并且會根據物體自身旋轉而旋轉, ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/71727.html
標籤:Python
上一篇:天池學習賽-NLP新聞文本分類(5/6)-Word2Vec+TextCNN模型
下一篇:python常用模塊
