QGraphicsScene繼承自QObject,是一個管理圖元的容器,與QGraphicsView合用能夠在2D屏幕上顯示如線、三角形、文本、自定義圖元等圖元。算法
QGraphicsScene是不可見的,只用於管理圖元。爲了查看場景,須要建立一個視圖組件。編程
一個場景分爲三個層:圖元層、前景層和背景層。場景的繪製老是從背景層開始,而後是圖形項層,最後是前景層。api
QGraphicsScene的責任之一是傳播來自視圖的事件。要發送一個事件到場景,須要構造一個繼承自QEvent的事件,使用QApplication::sendEvent()函數發送事件。event()函數負責派發事件到各個圖元。經常使用的事件會被便利事件處理函數處理,如鼠標按下事件會被mousePressEvent()函數處理。app
按鍵事件會被派發到焦點圖元。爲了設置焦點圖元,能夠調用setFocusItem()函數,或是圖元自身調用QGraphicsItem::setFocus()函數。調用focusItem()函數能夠獲取當前的焦點圖元。爲了兼容圖形組件,場景維護着本身的焦點信息。默認場景並無焦點,而且全部的按鍵事件會別丟棄。若是setFocus()函數被調用,或是場景中一個圖元得到了焦點,場景會自動得到焦點。若是場景有焦點,hasFocus()函數會返回true,按鍵事件會被髮送到焦點圖元。若是場景失去了焦點,而圖元有焦點(如調用clearFocus()函數),場景會維護圖元的焦點信息,一旦場景從新得到焦點,會確保最後一個有焦點的圖元得到焦點。框架
對於懸停效果,QGraphicsScene會派發懸停事件,若是某個圖元接受了懸停事件(調用QGraphicsItem::acceptHoverEvents()),當鼠標進入圖元的區域時,圖元會接收到一個GraphicsSceneHoverEnter事件。當鼠標繼續在圖元內部移動時,QGraphicsScene會發送GraphicsSceneHoverMove事件。當鼠標離開圖元的區域時,圖元會收到一個GraphicsSceneHoverLeave事件。ide
全部鼠標事件會被傳播到當前鼠標獲取的圖元。若是一個圖元接收了鼠標事件,並收到鼠標按下,圖元就是場景的鼠標獲取圖元。這個圖元會一直被鼠標獲取,直到圖元收到一個鼠標釋放事件。調用mouseGrabberItem()函數能夠知道當前鼠標獲取的圖元。函數
場景能夠傳遞來自視圖的事件,將事件傳遞給該點最頂層的圖元。若是一個圖元要接收鍵盤事件,那麼它必須得到焦點。並且,若是在場景中重寫了事件處理函數,那麼在該函數的最後必須調用場景默認的事件處理函數,只有這樣,圖元才能接收到該事件。oop
A、拖拽事件測試
[virtual protected] void dragEnterEvent(QGraphicsSceneDragDropEvent *event)動畫
拖入事件處理函數
[virtual protected] void dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
拖離事件梳理函數
[virtual protected] void dragMoveEvent(QGraphicsSceneDragDropEvent *event)
拖動事件處理函數
[virtual protected] void dropEvent(QGraphicsSceneDragDropEvent *event)
Drop事件處理函數
在以上拖拽事件處理函數中的末尾須要調用QGraphicsScene類相應的事件處理函數。
QGraphicsScene::dragEnterEvent(event);
QGraphicsScene::dragLeaveEvent(event);
QGraphicsScene::dragMoveEvent(event);
QGraphicsScene::dropEvent(event);
B、鼠標事件
[virtual protected] void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
鼠標移動處理函數
[virtual protected] void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
鼠標按下處理函數
[virtual protected] void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
鼠標釋放處理函數
在以上鼠標事件處理函數中的末尾須要調用QGraphicsScene類相應的事件處理函數。
QGraphicsScene::mouseMoveEvent(event);
QGraphicsScene::mousePressEvent(event);
QGraphicsScene::mouseReleaseEvent(event);
索引算法,是指在場景中進行圖元查找的算法。QGraphicsScene中提供了兩種選擇,在一個枚舉變量QGraphicsScene::ItemIndexMethod中定義,分別是:
QGraphicsSecne::BspTreeIndex :應用Binary Space Partition tree,適合於大量的靜態圖元,是默認值。
QGraphicsScene::NoIndex :不用索引,搜索場景中全部的圖元,適合於常常進行圖元的添加、移動和刪除等操做的狀況。
使用setItemIndexMethod()函數進行索引算法的更改。
圖元能夠放到場景的任何位置,場景的大小默認是沒有限制的。而場景的邊界矩形僅用於場景內部進行索引的維護。由於若是沒有邊界矩形,場景就要搜索全部的圖元,而後肯定出其邊界,這是十分費時的。因此若是要操做一個較大的場景,應該給出它的邊界矩形。
設置邊界矩形,可使用setSceneRect()函數。
場景最大的優點之一就是能夠快速的鎖定圖元的位置,即便有上百萬個圖元,items()函數也能在數毫秒的時間內鎖定一個圖元的位置。items()函數有幾個重載函數來方便的進行圖元的查找。若是在場景的一個點可能重疊着幾個圖元,可使用itemAt()函數返回最上面的一個圖元。
QGraphicsItem是圖元的基類。
自定義圖元,首先應該繼承QGraphicsItem,而後重寫他的兩個純虛公共函數boundingRect()和paint(),boundingRect()函數返回繪製圖元大概的區域,paint()函數用來繪製圖元內容。
boundingRect()函數有不少用處,場景在boundingRect()來創建它的圖元的index,視圖使用boundingRect來剪切可見的圖元,在從新繪製圖元時候,來決定相互重疊的部分,此外,圖元的碰撞檢測機制也使用的boundingRect()來提供一個高效的定點,在collidesWithItem()更好的碰撞算法創建在調用函數shape(),shape()函數以QpainterPath類型返回圖元的精準的輪廓。
場景不但願圖元的boundingRect()和shape()變化,除非該圖元被通告,若是想經過一些方法改變圖元的形狀,首先應該調用QgraphicsScene()來容許場景QgraphicsScene來刷新它的圖元記錄。
圖元沒有得到焦點時,事件只能從視圖傳遞到場景,不能傳遞到圖元。清除圖元的焦點函數爲clearFocus()。
paint()函數被QgrapicsView類調用來繪製圖元的內容,圖元默認是沒有背景或者填充顏色的。在函數中沒有被繪製的全部區域都將會發亮,能夠調用update()來重繪圖元,能夠選擇傳遞須要重繪的矩形區域(不是必須的)。取決於圖元在視圖中是否可見,圖元可能會也可能不會重繪,QgraphicsItem裏面沒有和 Qwidget::repaint()函數等價的圖元經過視圖來繪製,從父類圖元開始,而後是圖元自身,以上升的棧的順序,能夠經過調用setZValue()設置圖元的棧順序,經過zValue()來測試,具備低z-values的圖元比具備高z-value 的圖元先繪製,棧順序應用於兄弟圖元,父類圖元老是比子類圖元更早繪製。
全部的圖元都按照一個已經聲明的穩定的順序來繪製,聲明的順序決定了當在場景中點擊鼠標時候,哪一個圖元最早接受鼠標的輸入。一般狀況下,不須要擔憂圖元排序的問題,由於全部的圖元都按照一個在場景中聲明的天然的順序。
在一個棧中,子類圖元在父類圖元的上面,兄弟圖元按照插入場景的順序來入棧,若是你先添加圖元A ,而後是圖元B,而後是圖元C ,棧中的順序從下往上就是A、B、C。能夠調用setZvalue()來設置一個圖元的相對於另外一個圖元向上、向下或者兄弟棧順序。默認的Z值是0,具備一樣的Z值的圖元會按照插入的順序來入棧。能夠調用stackBefore()來備份子類圖元的列表,直接更正圖元的順序。
若是想讓子類圖元在父類圖元的後面,也就是先繪製子類圖元,而後再繪製父類圖元。能夠利用函數setFlag()設置ItemStacksBehindParent屬性給圖元。
QgraphicsItem從場景中經過sceneEvent()函數來接受事件,sceneEvent()函數經過一些方便的操做分散大部分事件。
ContextMenuEvent()函數接受上下文菜單事件,
FocusInEvent()和focusOutEvent()函數接受焦點進出事件,
hoverEnterEvent()、hoverMoveEvent()、hoverLeaveEvent() 接受鼠標懸浮移動和離開事件。
inputMethodEvent()函數處理輸入法事件,
keyPressEvent()和keyReleaseEvent()事件處理鍵盤按下和釋放事件
mousePressEvent()、mouseMoveEvent()、mouseReleaseEvent()、 mouseDoubleClickEvent()處理鼠標按下、移動、釋放、雙擊事件
經過安裝過濾器,能夠爲圖元過濾一些事件,與QT通常的事件過濾器不同,通常的過濾器只工做在Qobject及其子類。經過調用 installSceneEventFilter()爲圖元安裝事件過濾器後,被過濾的事件將會被虛函數sceneEventFilter()捕捉 到,能夠經過調用函數removeSceneEventFilter()來去除掉事件過濾器。
A、拖拽事件
GraphicsView框架爲視圖、場景、圖元提供拖拽支持。當視圖接收到拖拽事件,GraphicsView框架會將拖拽事件翻譯爲QGraphicsSceneDragDropEvent事件,再發送到場景,場景接管事件,把事件發送到光標下接受拖拽的第一個圖元。
從圖元開始拖拽時,建立一個QDrag對象,傳遞開始拖拽的QWidget的指針。圖元能夠同時被多個視圖觀察,但只有一個視圖能夠開始拖拽。拖拽在多數狀況下是從按下鼠標或是移動鼠標開始的,在mousePressEvent()或mouseMoveEvent()中,能夠從事件中獲得原始的QWidget指針。
要在場景中取拖拽事件,須要從新實現QGraphicsScene::dragEnterEvent()和QGraphicsItem子類裏任何與特定場景須要的事件處理器。圖元也能夠經過調用QGraphicsItem::setAcceptDrops()得到拖拽支持,爲了處理將要進行的拖拽,須要從新實現QGraphicsItem的dragEnterEvent()、dragMoveEvent()、
dropEvent()、dragLeaveEvent() 。
[virtual protected] void dragEnterEvent(QGraphicsSceneDragDropEvent *event)
[virtual protected] void dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
[virtual protected] void dragMoveEvent(QGraphicsSceneDragDropEvent *event)
[virtual protected] void dropEvent(QGraphicsSceneDragDropEvent *event)
B、鼠標事件
要在自定義圖元類中處理鼠標事件,須要重寫QGraphicsItem類中鼠標按下、鼠標移動、鼠標釋放的事件。
[virtual protected] void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
[virtual protected] void mousePressEvent(QGraphicsSceneMouseEvent *event)
[virtual protected] void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
實現圖元的動畫效果,也能夠在不一樣的層面進行。若是隻想控制一兩個圖元的動畫,通常在場景或視圖中實現。可是要是想讓一個圖元類的多個對象都進行一樣的動畫,那麼咱們就能夠在圖元類的構造函數中進行實現。
//圖元可得到焦點
setFlag(QGraphicsItem::ItemIsFocusable);
//圖元可移動
setFlag(QGraphicsItem::ItemIsMovable);
QGraphicsItemAnimation *anim = new QGraphicsItemAnimation;
//將圖元加入動畫對象中
anim->setItem(this);
//建立長爲1秒的時間線
QTimeLine *timeLine = new QTimeLine(1000);
//動畫循環次數爲0,表示無限循環
timeLine->setLoopCount(0);
//將時間線加入動畫類對象中
anim->setTimeLine(timeLine);
//在動畫時間的一半時圖形項旋轉180度
anim->setRotationAt(0.5,180);
//在動畫執行完時圖形項旋轉360度
anim->setRotationAt(1,360);
//開始動畫
timeLine->start();
圖元的移動,有多種方法實現,能夠在視圖或場景上控制,但對於不一樣類型的大量圖元,怎樣能一塊兒控制呢?在圖形視圖框架中提供了advance()槽函數,advance()函數在QGraphicsScene和QGraphicsItem中都有定義,在圖元類中的原型是advance(int phase)。實現流程是,利用QGraphicsScene類的對象調用QGraphicsScene的advance()函數,會執行兩次場景中全部圖元的advance(int phase)函數,第一次phase爲0,告訴全部圖形項即將要移動;第二次phase的值爲1,執行移動。
QTimer timer;
QObject::connect(&timer, SIGNAL(timeout()),scene, SLOT(advance()));
timer.start(1000);
至於圖元如何移動,須要重寫圖元類的advance()函數。
若是在自定義圖元類的構造函數中設置爲可移動,則圖元能夠直接使用鼠標拖拽。
setFlag(QGraphicsItem::ItemIsMovable);
QgraphicsItem支持座標轉換,對於簡單的轉換,能夠調用函數setRotation()或者setScale(),能夠傳遞一個轉換矩陣給函數setTransform(),對於一些更復雜的轉換,能夠經過調用函數setTransformations()來設置一系列組合的轉換。
圖元轉換從父類到子類進行彙集,所以若是一個父類圖元和子類圖元都旋轉90度,那麼子類圖元就旋轉了180度;若是父類圖元和子類圖元都放大了2X倍,那麼子類圖元就被放大4X倍,圖元的轉換不影響圖元的外觀,全部和外觀有關的函數(例如contains(),update()和全部的映射mapping函數)將會在本地座標中操做,QgraphicsItem提供函數sceneTransform(),將會返回圖元全部的轉換矩陣,scenePos()將會返回圖元在場景座標中的位置,從新設置圖元的矩陣,調用函數resetTransform()。
通常的轉換回產生一個不一樣的結果,取決於轉換應用的順序,轉換順序不一樣獲得結果將不一樣。
QVariant itemChange(GraphicsItemChange change, const QVariant & value)
itemChange函數被QGraphicsItem調用用來標識圖元的狀態改變了,經過重載itemChange函數,能夠對本身定義事件響應。參數change是改變的圖元的改變狀態參數,value是一個新的數據,類型取決於change,change是QGraphicsItem::GraphicsItemChange枚舉變量。
在itemChange函數內部調用函數時候要謹慎,不能在itemChange函數裏面調用setPos(),參數change是ItemPositionChange時,setPos()函數將會再次調用itemChange(ItemPositionChange),造成死循環。
void setFlag(GraphicsItemFlag flag, bool enabled = true)
void setFlags(GraphicsItemFlags flags)
flags設置爲圖元的屬性,若是圖元得到了光標,但flags沒有使能ItemsFocusable,圖元將會丟失光標,當圖元被選擇,但沒有使能ItemsSelectable,圖元會自動的失去選擇。
QPainterPath shape () const
以QPainterPath返回圖元在本地座標中的形狀,形狀能夠用來作不少事情,包括碰撞偵測,打擊測試,還有用來 QGraphicsScene::items() 函數
默認的函數調用boundingRect()返回一個簡單的矩形形狀,子類能夠重載boundingRect函數,爲非矩形的圖元返回一個更加精準的形狀,例如一個圓形的圖元能夠選擇返回一個橢圓形,用來得到更好的碰撞偵測效果。
QGraphicsView繼承自QAbstractScrollArea,繼承了QWidget的特性。
QGraphicsView提供了視圖窗口部件,使場景的內容可視化。能夠給一個場景關聯多個視圖,從而給一個數據集提供多個視口。視圖部件是一個滾動區域,能夠提供一個滾動條來顯示大型的場景。
在圖形視圖框架中,鼠標鍵盤等事件是從視圖進入的,視圖將事件傳遞給場景,場景再將事件傳遞給該點的圖元,若是該點有多個圖元,那麼就傳給最上面的圖元。爲了使事件能進一步傳播到場景,須要在從新實現事件處理函數時,在其最後將event參數傳給默認的事件處理函數。好比重寫了視圖的鼠標按下事件處理函數,那麼就在該函數的最後寫上QGraphicsView::mousePressEvent(event);
A、拖拽事件
在QGraphicView中提供了三種拖拽模式,分別是:
QGraphicsView::NoDrag :忽略鼠標事件,不能夠拖動。
QGraphicsView::ScrollHandDrag :光標變爲手型,能夠拖動場景進行移動。
QGraphicsView::RubberBandDrag :使用橡皮筋效果,進行區域選擇,能夠選中一個區域內的全部圖元。
能夠利用setDragMode()函數進行相應設置。
[virtual protected] void dragEnterEvent(QDragEnterEvent *event)
[virtual protected] void dragLeaveEvent(QDragLeaveEvent *event)
[virtual protected] void dragMoveEvent(QDragMoveEvent *event)
[virtual protected] void dropEvent(QDropEvent *event)
在以上拖拽事件處理函數中的末尾須要調用QGraphicsView類相應的事件處理函數。
QGraphicsView::dragEnterEvent(event);
QGraphicsView::dragLeaveEvent(event);
QGraphicsView::dragMoveEvent(event);
QGraphicsView::dropEvent(event);
B、鼠標事件
[virtual protected] void mouseMoveEvent(QMouseEvent *event)
[virtual protected] void mousePressEvent(QMouseEvent *event)
[virtual protected] void mouseReleaseEvent(QMouseEvent *event)
void setMouseTracking(bool enable)
在以上鼠標事件處理函數中的末尾須要調用QGraphicsView類相應的事件處理函數。
QGraphicsView::mouseMoveEvent(event);
QGraphicsView::mousePressEvent(event);
QGraphicsView::mouseReleaseEvent(event);
CustomView.h文件:
#ifndef CUSTOMVIEW_H #define CUSTOMVIEW_H #include <QGraphicsView> class CustomView : public QGraphicsView { Q_OBJECT public: CustomView(QWidget *parent = 0); protected: void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE; void dragLeaveEvent(QDragLeaveEvent *event) Q_DECL_OVERRIDE; void dragMoveEvent(QDragMoveEvent *event) Q_DECL_OVERRIDE; void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE; }; #endif // CUSTOMVIEW_H
CustomView.cpp文件:
#include "CustomView.h" #include <QDebug> CustomView::CustomView(QWidget *parent):QGraphicsView(parent) { } void CustomView::mousePressEvent(QMouseEvent *event) { qDebug() << "CustomView::mousePressEvent"; QGraphicsView::mousePressEvent(event); } void CustomView::mouseMoveEvent(QMouseEvent *event) { qDebug() << "CustomView::mouseMoveEvent"; QGraphicsView::mouseMoveEvent(event); } void CustomView::mouseReleaseEvent(QMouseEvent *event) { qDebug() << "CustomView::mouseReleaseEvent"; QGraphicsView::mouseReleaseEvent(event); } void CustomView::paintEvent(QPaintEvent *event) { qDebug() << "CustomView::paintEvent"; QGraphicsView::paintEvent(event); } void CustomView::dragEnterEvent(QDragEnterEvent *event) { qDebug() << "CustomView::dragEnterEvent"; QGraphicsView::dragEnterEvent(event); } void CustomView::dragLeaveEvent(QDragLeaveEvent *event) { qDebug() << "CustomView::dragLeaveEvent"; QGraphicsView::dragLeaveEvent(event); } void CustomView::dragMoveEvent(QDragMoveEvent *event) { setCursor(Qt::CrossCursor); qDebug() << "CustomView::dragMoveEvent"; QGraphicsView::dragMoveEvent(event); } void CustomView::dropEvent(QDropEvent *event) { qDebug() << "CustomView::dropEvent"; QGraphicsView::dropEvent(event); }
CustomScene.h文件:
#ifndef CUSTOMSCENE_H #define CUSTOMSCENE_H #include <QGraphicsScene> #include <QGraphicsSceneMouseEvent> #include <QPaintEvent> class CustomScene : public QGraphicsScene { Q_OBJECT public: CustomScene(QObject *parent = 0); protected: void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; void dragEnterEvent(QGraphicsSceneDragDropEvent *event) Q_DECL_OVERRIDE; void dragLeaveEvent(QGraphicsSceneDragDropEvent *event) Q_DECL_OVERRIDE; void dragMoveEvent(QGraphicsSceneDragDropEvent *event) Q_DECL_OVERRIDE; void dropEvent(QGraphicsSceneDragDropEvent *event) Q_DECL_OVERRIDE; }; #endif // CUSTOMSCENE_H
CustomScene.cpp文件:
#include "CustomScene.h" #include <QDebug> CustomScene::CustomScene(QObject *parent):QGraphicsScene(parent) { } void CustomScene::mousePressEvent(QGraphicsSceneMouseEvent *event) { qDebug() << "CustomScene::mousePressEvent"; QGraphicsScene::mousePressEvent(event); } void CustomScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { qDebug() << "CustomScene::mouseReleaseEvent"; QGraphicsScene::mouseReleaseEvent(event); } void CustomScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { qDebug() << "CustomScene::mouseMoveEvent"; QGraphicsScene::mouseMoveEvent(event); } void CustomScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event) { qDebug() << "CustomScene::dragEnterEvent"; QGraphicsScene::dragEnterEvent(event); } void CustomScene::dragLeaveEvent(QGraphicsSceneDragDropEvent *event) { qDebug() << "CustomScene::dragLeaveEvent"; QGraphicsScene::dragLeaveEvent(event); } void CustomScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event) { qDebug() << "CustomScene::dragMoveEvent"; QGraphicsScene::dragMoveEvent(event); } void CustomScene::dropEvent(QGraphicsSceneDragDropEvent *event) { qDebug() << "CustomScene::dropEvent"; QGraphicsScene::dropEvent(event); }
CustomItem.h文件:
#ifndef CUSTOMITEM_H #define CUSTOMITEM_H #include <QGraphicsItem> #include <QGraphicsSceneMouseEvent> class CustomItem : public QGraphicsItem { public: CustomItem(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) Q_DECL_OVERRIDE; QRectF boundingRect() const Q_DECL_OVERRIDE; protected: //鼠標事件 void mousePressEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_DECL_OVERRIDE; //拖拽事件 void dragEnterEvent(QGraphicsSceneDragDropEvent *event) Q_DECL_OVERRIDE; void dragLeaveEvent(QGraphicsSceneDragDropEvent *event) Q_DECL_OVERRIDE; void dragMoveEvent(QGraphicsSceneDragDropEvent *event) Q_DECL_OVERRIDE; void dropEvent(QGraphicsSceneDragDropEvent *event) Q_DECL_OVERRIDE; private: QColor color; }; #endif // CUSTOMITEM_H
CustomItem.cpp文件:
#include "CustomItem.h" #include <QDebug> #include <QPainter> #include <QCursor> #include <QPen> CustomItem::CustomItem() { color = Qt::red; setFlag(QGraphicsItem::ItemIsFocusable); //設置圖元爲可移動的 setFlag(QGraphicsItem::ItemIsMovable); setAcceptDrops(true); } void CustomItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); qDebug() << "CustomItem::paint"; if(hasFocus()) { painter->setPen(QPen(QColor(255,255,255,200))); } else { painter->setPen(QPen(QColor(100,100,100,100))); } painter->setBrush(color); painter->drawRect(-10, -10, 20, 20); } QRectF CustomItem::boundingRect() const { qreal adjust = 0.5; return QRectF(-10 - adjust, -10 - adjust, 20 + adjust, 20 + adjust); } void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_UNUSED(event); qDebug() << "CustomItem::mousePressEvent"; setCursor(Qt::OpenHandCursor); } void CustomItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { setCursor(Qt::DragMoveCursor); qDebug() << "CustomItem::mouseMoveEvent"; } void CustomItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { qDebug() << "CustomItem::mouseReleaseEvent"; setCursor(Qt::ArrowCursor); } void CustomItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event) { setCursor(Qt::CrossCursor); qDebug() << "CustomItem::dragEnterEvent"; } void CustomItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event) { setCursor(Qt::ForbiddenCursor); qDebug() << "CustomItem::dragLeaveEvent"; } void CustomItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event) { setCursor(Qt::CrossCursor); qDebug() << "CustomItem::dragMoveEvent"; } void CustomItem::dropEvent(QGraphicsSceneDragDropEvent *event) { setCursor(Qt::WaitCursor); qDebug() << "CustomItem::dropEvent"; }
#include "CustomScene.h" #include "CustomView.h" #include "CustomItem.h" #include <QApplication> #include <QTime> int main(int argc, char *argv[]) { QApplication a(argc, argv); qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime())); CustomScene scene; scene.setSceneRect(-200, -150, 400, 300); for(int i = 0; i < 5; ++i) { CustomItem *item = new CustomItem; item->setPos(i * 50 - 90, -50); scene.addItem(item); } CustomView view; view.setScene(&scene); view.show(); return a.exec(); }