圖形視圖框架
The Graphics View Framework
關(guān)鍵詞翻譯對照表:
Graphics View:圖形視圖。
Scene:場景 /場景管理器( Scene同時擔(dān)負著管理場景中的對象,建立索引等工作)。
Item:這里翻譯為對象, Graphics View Framework下的 GraphicsItem是場景中可以被顯示的元素。這里翻譯成對象便于理解。
Graphics Item:圖形對象。
Event:事件,等同于 Windows下的消息。
正文:
圖形視圖( Graphics View )提供了支持大量自定義的二維圖形對象( Item ,這里譯為 “ 對象 ” ,方便大家理解)交互( Interaction )的管理器,以及一個支持縮放和旋轉(zhuǎn)操作的視圖 widget 用于顯示這些元素。
該框架包含了事件( Event ,在 Windows 下可以理解為 “ 消息 ” )傳播的框架,支持場景管理器中精確的交互能力,以雙精度浮點數(shù)表示對象位置、大小等屬性的變化。圖形元素還能處理鍵盤事件、鼠標(biāo)按下 / 移動 / 釋放和雙擊的時間,同時也能跟蹤鼠標(biāo)移動。
圖形視圖使用 BSP 樹( Binary Space Partitioning ,二叉空間分割)提供對圖形對象的快速查找,可以想像,即使是包含數(shù)以百萬計對象的超大場景,也能夠進行實時顯示。
圖形查看 Qt 中引入 4.2 ,取代其前身
QCanvas。 如果您要從
QCanvas 中移植過來,見
移植到圖形視圖 。
主題:
圖形視圖架構(gòu)場景
視圖
對象
圖形視圖框架中的類
圖形視圖坐標(biāo)系對象坐標(biāo)
場景坐標(biāo)
視圖坐標(biāo)
坐標(biāo)映射
主要特點縮放和旋轉(zhuǎn)
打印
拖放
鼠標(biāo)指針和 tooltip
動畫
OpenGL渲染
元素組
widgets和布局QGraphicsWidget
QGraphicsLayout
嵌入式 widget支持
性能浮點運算指令
圖形視圖架構(gòu)
圖形視圖提供基于圖像對象的方式來實現(xiàn) model-view的編程模式,這一點很像例程 InterView中的輔助類 QTableView, QTreeView和QListView。不同的視圖可以顯示一個場景,場景則包含了不同的幾何形狀的對象。
場景
QGraphicsScene提供了圖形視圖的場景管理器。場景管理器有如列職責(zé):
提供一個用于管理大量對象的快速接口
將事件傳遞到每個對象上
管理對象的狀態(tài)
提供未進行坐標(biāo)變換的渲染功能,主要用于打印
場景管理器是圖形對象 QGraphicsItem的容器。調(diào)用 QGraphicsScene::addItem()將對象添加到場景中后,你就可以通過調(diào)用場景管理器中的不同的查找函數(shù)來查找其中的圖形對象。 QGraphicsScene::items()函數(shù)及其重載函數(shù)可以返回所有通過點、矩形多邊形或路徑等不同方式選中的所有對象。 QGraphicsScene::itemAt()返回在指定點位置上最上面的對象。所有找到的對象保持按照層疊遞減的排列順序(即第一個返回的對象是最頂層,和最后一個項目是最底層的對象)。
QGraphicsScene scene;
QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100));
QGraphicsItem *item = scene.itemAt(50, 50);
// item == rect
QGraphicsScene的事件傳遞機制負責(zé)將場景時間傳遞給圖形對象,同時也管理對象之間的時間傳遞。如果場景在某個位置得到鼠標(biāo)按下的消息,就將該事件傳遞給這個位置上的對象。
QGraphicsScene同時還管理對象的狀態(tài),例如對象的選中狀態(tài)和焦點狀態(tài)。您可以通過調(diào)用 QGraphicsScene::setSelectionArea(),傳遞一個任意形狀給場景管理器,選中其中包含的對象。此功能也是 QGraphicsView 中拉框選擇( rubber band)的基礎(chǔ)。通過調(diào)用QGraphicsScene::selectedItems()可以獲取當(dāng)前選擇集中的所有對象。另外一種通過
QGraphicsScene 來管理的狀態(tài)是:一個圖形對象是否能夠相應(yīng)鍵盤的焦點切換 .你可以調(diào)用
QGraphicsScene::setFocusItem ()或者
QGraphicsItem::setFocus ()將鍵盤焦點切換到對于的圖形對象上,或者通過
QGraphicsScene::focusItem ()獲取當(dāng)前的焦點對象。
最后,
QGraphicsScene 允許你通過
QGraphicsScene::render ()將部分場景繪制到 paint device上。你可以在本文檔中關(guān)于“打印”的章節(jié)了解更多關(guān)于這一點的更多細節(jié)。
視圖
QGraphicsView 提供了視圖 widget,將場景中的內(nèi)容顯示出來。你可以用幾個不同的視圖來觀察同一個場景,從而實現(xiàn)對于同一數(shù)據(jù)集的不同 viewport。該 Widget同時也是 scroll area,為大場景提供滾動條。如果要啟用 OpenGL支持,可調(diào)用
QGraphicsView::setViewport 將
QGLWidget 設(shè)置為其 viewport。
QGraphicsScene scene;
myPopulateScene(&scene);
QGraphicsView view(&scene);
view.show();
視圖接受鍵盤和鼠標(biāo)消息,并將這些消息轉(zhuǎn)換成場景事件(同時將視圖坐標(biāo)轉(zhuǎn)換為場景坐標(biāo)),然后將事件發(fā)送給可見視圖。
通過操作變換矩陣
QGraphicsView::transform ,視圖可以對場景的坐標(biāo)系統(tǒng)進行變換,從而實現(xiàn)縮放、旋轉(zhuǎn)等高級查看功能。為了方便起見, QGraphicsView同時也提供了在視圖坐標(biāo)和場景坐標(biāo)之間變化的函數(shù):
QGraphicsView::mapToScene () 和
QGraphicsView::mapFromScene ()。
對象
QGraphicsItem 是場景中所有圖形獨享的基類。圖形視圖提供了幾種標(biāo)準(zhǔn)的對象:矩形 (
QGraphicsRectItem ), 橢圓 (
QGraphicsEllipseItem ) 和文本對象 (
QGraphicsTextItem )。但是
QGraphicsItem 最強大的功能是支持定制的圖形對象。
QGraphicsItem 支持如下特征:
· 鼠標(biāo)按下、移動、釋放和雙擊事件,同時還支持鼠標(biāo)懸浮事件、滾輪事件和上下文菜單事件。
· 鍵盤輸入焦點和鍵盤事件。
· 拖放。
· 組合:通過父對象 -子對象進行組合,或者通過
QGraphicsItemGroup 組合。
· 碰撞檢測。
與
QGraphicsView 類似,處于局部坐標(biāo)系下的圖形對象,也提供了圖形對象和場景之間的映射函數(shù)。和
QGraphicsView 一樣,圖形對象同時還可以通過矩陣來變換其自身的坐標(biāo)系統(tǒng),這一點對于單個圖形對象的旋轉(zhuǎn)和縮放非常有用。
圖形視圖架構(gòu)
個圖形對象可以包含其他對象(子對象)。父對象的變換矩陣同樣也會應(yīng)用到子對象上。但是,不管一個對象累積了多少變換, QGraphicsItem::collidesWith()仍然會在局部坐標(biāo)系下進行計算。
QGraphicsItem 通過
QGraphicsItem::shape 和 QGraphicsItem::collidesWith來實現(xiàn)碰撞檢測,這兩個函數(shù)都是虛函數(shù)。
QGraphicsItem 通過
QGraphicsItem::shape 獲取局部坐標(biāo)系下的
QPainterPath 對象,來完成碰撞檢測。不過如果你想提供你自己的碰撞檢測機制,你可以通過自定義 QGraphicsItem::collidesWith函數(shù)來實現(xiàn)。
圖形視圖架構(gòu) 中的類
下面的類提供了創(chuàng)建交互 式應(yīng)用 程序的框架:
QAbstractGraphicsShapeItem所有路徑對象的共同基類
QGraphicsAnchor代表了 QGraphicsAnchorLayout 中 兩個項目之間的 anchor
QGraphicsAnchorLayout如何將 widgets anchor到圖形視圖中
QGraphicsEffect所有圖形特效的基類
QGraphicsEllipseItem橢圓對象,可以直接添加到 QGraphicsScene
QGraphicsGridLayout管理 widgets在圖形視圖中的布局
QGraphicsItem在 QGraphicsScene 中所有圖形對象的基類
QGraphicsItemAnimation為 QGraphicsItem 提供簡單的 動畫支持
QGraphicsItemGroup將多個圖形對象組合成一個對象
QGraphicsLayout圖形視圖中所有布局類的基類
QGraphicsLayoutItem允許布局類管理的自定義對象
QGraphicsLineItem直線對象,可以直接添加到 QGraphicsScene
QGraphicsLinearLayout管理 widgets在圖形視圖中的的水平或者垂直方向上的布局
QGraphicsObject所有需要處理信號 /槽 /屬性的圖形對象。
QGraphicsPathItem路徑對象,可以直接添加到 QGraphicsScene
QGraphicsPixmapItem位圖對象,可以直接添加到 QGraphicsScene
QGraphicsPolygonItem多邊形對象,可以直接添加到 QGraphicsScene
QGraphicsProxyWidgetwidget代理,用于將一個 QWidget 對象嵌入 一個 QGraphicsScene 中
QGraphicsRectItem矩形對象,可以直接添加到 QGraphicsScene
QGraphicsScene管理大量二維圖形對象的管理器
QGraphicsSceneContextMenuEvent在圖形視圖框架中的上下文菜單事件
QGraphicsSceneDragDropEvent圖形視圖框架中的拖放拖放事件
QGraphicsSceneEvent圖形視圖框架中所有事件的基類
QGraphicsSceneHelpEventTooltip顯示時發(fā)出的事件
QGraphicsSceneHoverEvent圖形視圖框架中的懸停事件
QGraphicsSceneMouseEvent圖形視圖框架中的鼠標(biāo)事件
QGraphicsSceneMoveEvent圖形視圖框架中的 widget移動事件
QGraphicsSceneResizeEvent圖形視圖框架中的 widget大小改變的事件視
QGraphicsSceneWheelEvent圖形視圖框架中的鼠標(biāo)滾輪時間
QGraphicsSimpleTextItem簡單的文本對象,可以直接添加到 QGraphicsScene 中
QGraphicsSvgItem可以用來呈現(xiàn)的 SVG 文件內(nèi)容的 QGraphicsItem 對象
QGraphicsTextItem文本對象,可以直接添加到 QGraphicsScene ,用于 顯示帶格式的文本
QGraphicsTransform創(chuàng)建 QGraphicsItems 高級矩陣變換的抽象類
QGraphicsView顯示 QGraphicsScene 內(nèi)容的 widget
QGraphicsWidgetQGraphicsScene 中所有 widget的基類
QStyleOptionGraphicsItem用于描述繪制 QGraphicsItem 所需的 參數(shù)
圖形視圖坐標(biāo)系
圖形視圖建立在直角坐標(biāo)系基礎(chǔ)上,圖形對象的位置和幾何形狀由兩組數(shù)據(jù)來表示: x坐標(biāo)和 y坐標(biāo)。如果使用未變換的視圖來觀察場景,場景中的一個單元將會表現(xiàn)為屏幕上的一個像素。
注意 :圖形視圖使用了 Qt的坐標(biāo)系,不支持反轉(zhuǎn)的 y軸坐標(biāo)系統(tǒng)(即 y向上為正方向)。
圖形視圖使用了三種有效的坐標(biāo)系:對象坐標(biāo),場景坐標(biāo)和視圖坐標(biāo)。為了簡化你的實現(xiàn)工作,圖形視圖提供了一系列非常方便的函數(shù)來進行三個坐標(biāo)系下的坐標(biāo)變換。
繪制的時候,圖形視圖的場景坐標(biāo)對應(yīng)于 QPainter的邏輯坐標(biāo),視圖坐標(biāo)與設(shè)備坐標(biāo)一直。在
The Coordinate System 一文中你可以閱讀更多關(guān)于邏輯坐標(biāo)和設(shè)備坐標(biāo)關(guān)系的內(nèi)容。
對象坐標(biāo)系
圖形對象建立其自身的局部坐標(biāo)系下。該坐標(biāo)系通常以中心點( 0, 0)為中心,同時該中心點也是各種矩陣你變換的中心。對象坐標(biāo)系下的幾何元素通常用點、線或者矩形來表示。
創(chuàng)建自定義圖形對象的時候,你只需關(guān)注對象坐標(biāo)系即可。
QGraphicsScene 和
QGraphicsView 會執(zhí)行所有相關(guān)的變換,這樣一來我們實現(xiàn)自定義對象就容易多了。比如說,當(dāng)你接受鼠標(biāo)按下或者拖拽事件的時候,事件位置已經(jīng)被轉(zhuǎn)換到了對象坐標(biāo)系下。類似的,對象的包圍盒和形狀都是基于對象坐標(biāo)系的。
對象的位置 是對象坐標(biāo)系下的中心點在其父對象坐標(biāo)系下的位置。對于所有沒有父對象的對象來說,場景就是其父對象。因此最頂層對象的位置就是其在場景中的位置。
子對象坐標(biāo)系是相對于父對象坐標(biāo)系來說的一個概念。如果子節(jié)點沒有進行矩陣變換,那么在子對象坐標(biāo)系和父對象坐標(biāo)系的差異就和這些對象在父對象中的偏移。比如說,如果一個未經(jīng)變換的子對象精確的位于父對象的中心點,那么這兩個對象的坐標(biāo)系就是完全一致的。如果子對象的位置是( 10, 0),那么子對象的( 0, 10)點就位于父對象的( 10, 10)點的位置。
由于對象的位置和變換是相對于父對象來說的,因此雖然父對象的變換隱式地變換了子對象,子對象的坐標(biāo)系不會因父對象坐標(biāo)系改變而改變。在上面的例子中,即使父對象經(jīng)過了旋轉(zhuǎn)和縮放,子對象的( 0, 10)點依然相對于父對象是( 10, 10)點。不過相對于場景來說,子對象將隨著父對象進行變換和 偏移 。如果父對象縮放了( 2x, 2x),那么子對象在場景坐標(biāo)系下將會位于( 20, 0)的位置,同時其( 10, 0)點將會對應(yīng)于場景中的( 40, 0)點。
不管對象自身或者父對象進行了什么樣的變化,
QGraphicsItem的函數(shù)一般總是表示在對象坐標(biāo)系下的位置,其操作也作用于對象坐標(biāo)系內(nèi)。比如,一個對象的包圍盒(
QGraphicsItem::boundingRect ())總是在對象坐標(biāo)系下給出的。但是
QGraphicsItem::pos 是例外之一,該函數(shù)表示其在父對象中的位置 。(致謝:此處由
tnt_vampire 指出并修正 ,見注釋)
場景坐標(biāo)系
場景表示了其中所有對象的基礎(chǔ)坐標(biāo)系。場景坐標(biāo)系描述了每一個頂層對象的位置,同時也是所有從視圖傳遞到場景的事件的變化基礎(chǔ)。場景中的每一個對象都有其在場景中的位置和包圍盒(
QGraphicsItem::scenePos (),
QGraphicsItem::sceneBoundingRect ()),另外,也有其自身的位置和包圍盒。場景位置描述了對象在場景坐標(biāo)系下的位置,場景包圍盒則提供給 QGraphicsScene來決定場景中的哪一塊區(qū)域已經(jīng)被改變了。場景中的變化通過
QGraphicsScene::changed ()信號發(fā)出,參數(shù)是場景坐標(biāo)系下的矩形列表。
視圖坐標(biāo)系
視圖坐標(biāo)系是 widget 的坐標(biāo)系。視圖坐標(biāo)系下的每個單位對應(yīng)于一個像素。對于該坐標(biāo)系來說比較特殊的一點是,它是相對于 widget 或者 viewport 的坐標(biāo)系,不會受到被顯示的場景的影響。
QGraphicsView 的 viewport 左上角坐標(biāo)總是( 0 , 0 ),右下角坐標(biāo)總是( viewport 寬度, viewport 高度)。所有的鼠標(biāo)事件和拖拽事件都在視圖坐標(biāo)系下接收,你需要將這些坐標(biāo)映射到場景中后才能與場景中的圖形對象進行交互。
坐標(biāo)映射
通常當(dāng)我們處理場景中的對象的時候,坐標(biāo)變換將會非常有用,我們可以把坐標(biāo)或者任意形狀從場景變換到對象坐標(biāo)系下,從一個對象坐標(biāo)系變換到另一個對象坐標(biāo)系,或者從視圖變換到場景。例如當(dāng)你用鼠標(biāo)點擊了 QGraphicsView的 viewport,你可以向場景管理器查詢當(dāng)前鼠標(biāo)下方的對象(調(diào)用
QGraphicsView::mapToScene ()變換坐標(biāo),然后通過
QGraphicsScene::itemAt ()查詢對象)。如果你想知道一個對象處于 viewport中的位置,你可以調(diào)用對象的函數(shù)
QGraphicsItem::mapToScene () ,然后在調(diào)用視圖的函數(shù)
QGraphicsView::mapFromScene () 。最后,如果你想查找位于一個橢圓區(qū)域內(nèi)的對象,你可以把一個
QPainterPath 對象傳遞給 mapToScene()然后將變換之后的 path傳遞給
QGraphicsScene::items ()。
你可以通過調(diào)用
QGraphicsItem::mapToScene () 將坐標(biāo)或者任意形狀 映射到對象的場景中去,同樣也可以通過調(diào)用
QGraphicsItem::mapFromScene ()將其映射回來。你也可以調(diào)用
QGraphicsItem::mapToParent ()將對象映射到其父對象的坐標(biāo)系下,同樣也可以通過調(diào)用
QGraphicsItem::mapFromParent ()將其映射回來。甚至可以用過調(diào)用
QGraphicsItem::mapToItem () 和
QGraphicsItem::mapFromItem ()在不同的對象的坐標(biāo)系之間進行映射。所有的映射函數(shù)均支持點、舉行、多邊形和路徑。
在視圖和場景之間也存在著同樣的映射函數(shù):
QGraphicsView::mapFromScene () 和
QGraphicsView::mapToScene ()。要從視圖映射到對象,第一步是映射到場景,然后才能從場景映射到對象坐標(biāo)系下。
主要特點
縮放和旋轉(zhuǎn)
和 QPainter一樣 QgraphicsView也可以通過
QGraphicsView::setMatrix ()支持仿射變換。通過這種將變換矩陣應(yīng)用到視圖上的方式,你能很容易的添加對縮放和旋轉(zhuǎn)等操作的支持。
這里是一個如何通過 QGraphicsView子類來實現(xiàn)旋轉(zhuǎn)和縮放操作的例子:
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); }
...
};
槽( Slots)可以關(guān)聯(lián)到啟用了“
autoRepeat ”屬性的 QToolButtons。在變換視圖的過程中, QgraphicsView始終保持與視圖中心對齊。參閱例程
Elastic Nodes 了解如何實現(xiàn)這種基本的縮放操作。
打印
圖形視圖通過其繪制函數(shù)
QGraphicsScene::render () 和
QGraphicsView::render ()提供了非常簡單的打印功能。這兩個函數(shù)提供了相同的 API:你可以讓場景或者視圖將全部或者部分的內(nèi)容會知道任何 paint device(注: QImage、 QPrinter、 QWidget均屬于 paint device)上,只需要將將 QPainter傳給繪制函數(shù)即可。下面的例子展示了如何利用 QPrinter將整個場景繪制到一頁上:
QGraphicsScene scene;
scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green));
QPrinter printer;
if (QPrintDialog(&printer).exec() == QDialog::Accepted) {
QPainter painter(&printer);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
}
場景和視圖繪制函數(shù)的區(qū)別在于,前者操作的是場景坐標(biāo),后者操作的則是視圖坐標(biāo)。 QGraphicsScene::render多用于打印未經(jīng)變換的整個場景,比如將幾何數(shù)據(jù)圖表打印出來,或者打印文本文檔。 QGraphicsView::render則比較適合用于抓取屏幕截圖,其缺省行為是將 viewport中確切的內(nèi)容繪制到所提供的 painter上。
QGraphicsScene scene;
scene.addRect(QRectF(0, 0, 100, 200), QPen(Qt::black), QBrush(Qt::green));
QPixmap pixmap;
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing);
scene.render(&painter);
painter.end();
pixmap.save("scene.png");
當(dāng)源區(qū)域和目標(biāo)區(qū)域不匹配的時候,源區(qū)域內(nèi)容將會被縮放到適合目標(biāo)區(qū)域。通過傳遞
Qt::AspectRatioMode 參數(shù)給繪制函數(shù),你可以在需要縮放的時候選擇保持或者忽略比例進行縮放。
拖放
由于
QGraphicsView 直接從
QWidget 繼承,因此 QGraphicsView也提供了和
QWidget 一樣的拖放功能。另外,為了方便起見,圖形視圖框架為場景中的每個對象提供了拖放支持。當(dāng) view對象接收到一個拖拽消息的時候,它將其轉(zhuǎn)換為拖放事件
QGraphicsSceneDragDropEvent,然后將其轉(zhuǎn)發(fā)給場景管理器。場景管理器則會接管該事件,并將其發(fā)送給鼠標(biāo)下面第一個接受拖拽消息的對象。
要拖拽一個對象,只需要創(chuàng)建一個
QDrag 對象,將指針傳給開始拖拽的 widget。對象可以同時被多個視圖觀察,但是只有一個視圖可以進行拖拽。在大多數(shù)情況下,拖拽都從鼠標(biāo)按下或者移動開始,因此在 mousePressEvent()或者 mouseMoveEvent()事件中,你可以從事件中拿到原始 widget的指針,例如:
void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
QMimeData *data = new QMimeData;
data->setColor(Qt::green);
QDrag *drag = new QDrag(event->widget());
drag->setMimeData(data);
drag->start();
}
如果你想攔截發(fā)送給場景的拖放消息,只需要實現(xiàn)
QGraphicsScene::dragEnterEvent ()事件,選擇你需要處理的事件,然后在
QGraphicsItem:: dragEnterEvent 中進行相應(yīng)處理即可。你可以到
QGraphicsScene 的文章中查看更多關(guān)于拖放的內(nèi)容。對象可以通過調(diào)用
QGraphicsItem::setAcceptDrops 來允許或者禁止對拖放的支持。可以通過實現(xiàn)
QGraphicsItem::dragEnterEvent (),
QGraphicsItem::dragMoveEvent (),
QGraphicsItem::dragLeaveEvent (), 和
QGraphicsItem::dropEvent () 這幾個事件來處理拖動。
鼠標(biāo)指針和 tooltip
和 QWidget一樣, QGraphicsItem也支持設(shè)置鼠標(biāo)和 tooltip。當(dāng)鼠標(biāo)進入對象區(qū)域(由
QGraphicsItem::contains 檢測)時,通過 QGraphicsView來設(shè)置鼠標(biāo)和 tooltip。
你也調(diào)用
QGraphicsView::setCursor 設(shè)置視圖的確實鼠標(biāo)指針。在
Drag and Drop Robot 這里例子中有實現(xiàn) tooltip和鼠標(biāo)指針的代碼。
動畫
圖形視圖在幾個層面上提供了對動畫的支持。你可以用 Animation Framework輕松地設(shè)置動畫:只需要讓你的對象從
QGraphicsObject 繼承,然后將
QPropertyAnimation 綁定到上面。
QPropertyAnimation 允許你通過對對象的屬性進行操作來實現(xiàn)動畫效果。
另外一個選擇是創(chuàng)建一個從
QObject 和
QGraphicsItem 繼承的對象。該對象設(shè)置自己的時鐘,然后在
QObject::timerEvent 中控制動畫。
第三個選擇僅限于與 Qt3中的
QCanvas 兼容。調(diào)用
QGraphicsScene::advance 從而使
QGraphicsItem::advance 得以執(zhí)行。
OpenGL繪制
要使用 OpenGL進行繪制,只需簡單地創(chuàng)建一個新的
QGLWidget 對象,并調(diào)用
QGraphicsView::setViewport () 將其作為視口設(shè)置為視圖即可。如果你希望使用 OpenGL 的反鋸齒,則需要 OpenGL 支持采樣緩存(請參見
QGLFormat::sampleBuffers () )。
QGraphicsView view(&scene);
view.setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
對象編組
通過將一個對象設(shè)置為另一個對象的子對象,你就可以得到對象編組最重要的功能:對象會一起移動,所有變換都會從父對象傳播到子對象中。
另外,
QGraphicsItemGroup 是一個特殊的對象,它提供了對子對象事件的支持,同時還提供了用于添加和刪除子對象的接口。將一個對象添加到
QGraphicsItemGroup 將保持對象原始的位置和坐標(biāo)變換,不過重新設(shè)置對象的父對象則會導(dǎo)致對象重新定位到相對于父對象的位置。為了方便起見,你可以 調(diào)用
QGraphicsScene::createItemGroup ()來 創(chuàng)建
QGraphicsItemGroup 對象。
Widgets和布局
Qt4.4引入了對幾何體和對布局敏感的對象的支持,具體實現(xiàn)在
QGraphicsWidget 中。這一特殊的基類對象和 QWidget類似,但是不想 QWidget,它沒有從 QPaintDevice繼承,而是從 QGraphicsItem。這樣就允許你完全實現(xiàn)能夠處理事件、信號與槽、大小調(diào)整策略的 widget,同時你還可以通過
QGraphicsLinearLayout 和
QGraphicsGridLayout 來管理 widget的幾何元素。
QGraphicsWidget
QGraphicsWidget建立在 QGraphicsItem之上,具有 QGraphicsItem的所有功能,保持了較小的資源占用,同時提供了兩者的優(yōu)勢:來自 QWidget的額外的功能,比如樣式、字體、調(diào)色板、布局、幾何形狀,來自 QGraphicsItem的分辨率獨立性和坐標(biāo)變換的支持。因為幾何視圖使用真實的坐標(biāo)而不是整數(shù),因此 QGraphicsWidget的幾何形狀函數(shù)可以同時操作 QRectF和 QPointF。同時也能應(yīng)用到邊框的大小、邊距和間距上,例如在 QGraphicsWidget上將對象的邊距設(shè)置為( 0.5, 0.5, 0.5, 0.5)是非常常見的。你也可以創(chuàng)建子 widget對象,甚至是“頂級”窗口。在某些情況下,你甚至可以將圖形視圖用于高級多文檔界面的應(yīng)用程序。
QGraphicsWidget支持部分 QWidget屬性,包括窗口標(biāo)志位和屬性,但是并非全部支持。你需要通過
QGraphicsWidget 文檔獲取哪些支持以及哪些不支持的完整列表。例如,你可以在創(chuàng)建 QGraphicsWidget時賦予 Qt::Window標(biāo)志,從而得到封裝的窗口,但是圖形視圖目標(biāo)并不支持 Qt::Sheet和 Qt::Drawer標(biāo)志,這兩者在 Mac Os X上非常常見。
QGraphicsWidget的功能將會逐步豐富起來,這一點由社區(qū)的反饋決定。
QGraphicsLayout
QGraphicsLayout是第二代布局框架的內(nèi)容之一,專門為 QGraphicsWidget設(shè)計。其 API和 QLayout非常相似。你可以在
QGraphicsLinearLayout 或者
QGraphicsGridLayout 中對 widget或者子布局進行管理,也可以通過派生 QgraphicsLayout實現(xiàn)你自己的布局類,你還可以通過派生
QGraphicsLayoutItem 來實現(xiàn)你自己的 QGraphicsItem對象的適配器從而將其加入到布局中。
嵌入式 widget的支持
圖形視圖對將任何 widget嵌入到場景中提供無縫的支持。你可以嵌入簡單的 widget,比如 QLineEdit或者 QPushButton,也可以是復(fù)雜的 widget,比如 QTabWidget,甚至是完整的主窗口。要將 widget嵌入場景中,只需要簡單地調(diào)用
QGraphicsScene::addWidget 或者創(chuàng)建一個
QGraphicsProxyWidget 對象并將 widget手工的嵌入其中。通過
QGraphicsProxyWidget 圖形視圖能夠完全繼承客戶端 widget對象的功能,包括其鼠標(biāo)指針、 tooltip、鼠標(biāo)事件、平板電腦相關(guān)事件、鍵盤事件、子窗口、動畫、彈出(比如 QComboBox或者 QCompleter),以及 widget輸入焦點和激活狀態(tài)。
QGraphicsProxyWidget 甚至集成了嵌入式 widget的 tab切換順序,這樣你就可以通過 tab鍵讓焦點進入或者移出嵌入式 widget。你甚至可以嵌入一個新的 QGraphicsView到你的場景中,從而提供復(fù)雜的嵌套的視圖。
性能
精度浮點數(shù)指令
為了精確和快速的將坐標(biāo)變換和特效應(yīng)用到圖形對象上,圖形視圖在編譯的時候默認(rèn)用戶的硬件能夠為浮點指令提供合理的性能。
很多工作站和桌面電腦都配備了適當(dāng)?shù)挠布砑铀龠@種類型的計算,但是一些嵌入式設(shè)備可能僅僅提供了處理數(shù)學(xué)運算的庫,或者需要用軟件來模擬浮點指令。
這樣,在某些設(shè)備上,某些類型的特效可能要比預(yù)期的慢。有可能可以在其他方面進行優(yōu)化來彌補性能上的損失,比如說用 OpenGL來繪制場景。不過,如果優(yōu)化本身是依賴于浮點計算硬件的話,可能都會帶來性能上的損失。
轉(zhuǎn)載請保留出處:
http://blog.csdn.net/aladdina