在QGraphicsView框架中實現圖像拖拽,固然可以使用滑動條拖動,但是如果可以使用鼠標在圖像上面進行拖動,豈不是更方便,但遙感處理軟件都有這種功能嘛。
要實現拖拽,首先就要獲得鼠標事件,通常是按下鼠標左鍵,然后拖動圖像,鼠標釋放時拖動結束。核心的問題就是如何實現圖像的移動。這里有兩個思考的出發點:
一個就是根據圖像項在場景中的坐標;
另一個就是通過改變滑動條的值。
前者沒有研究清楚,未實現,采用后者實現了,后者實現也簡單。因為GraphicsView自身帶有滑動條,所以可以設置滑動條的值來移動圖像。
本文使用改變滑動條的值實現,要點有兩個:一是重寫QGraphicsView類中的鼠標事件,二是捕捉鼠標移動的長度,然后使滑動條改變相應的值,從而實現圖像移動。
1.重寫鼠標事件
這里在Qt設計師中將QGraphicsView類進行提升,也即自定義一個類,該類繼承自QGraphicsView,將該類作為顯示圖像的部件,假設類的名稱為ImgGraphicsView,則在類ImgGraphicsView中重寫鼠標按下、鼠標移動、鼠標釋放的事件
鼠標事件的邏輯為:先按下鼠標,然后鼠標移動,鼠標移動時圖像跟着移動,鼠標釋放,圖像停止移動。
所以處理的是鼠標左鍵,鼠標右鍵不管。而且鼠標移動是在鼠標按下后捕捉的,因此要進行鼠標跟蹤的設置
setMouseTracking(false);
詳見幫助文檔:
還需設置一個標識符,用於判斷鼠標左鍵是否按下。移動圖像時需要知道的信息有移動前鼠標所在坐標和移動后鼠標所在坐標,兩坐標之差就是圖像要移動的距離(分X軸和Y軸),然后在滑動條當前值加上增加的移動距離即可得到新的滑動條值,然后圖像就移動了。這里最關鍵的就是如何將鼠標坐標值傳給主界面中的ImgGraphicsView部件,實現圖像移動。
鼠標左鍵點下時坐標:x1,y1
鼠標移動時的坐標:x2,y2
鼠標移動時的坐標值是在ImgGraphicsView類中實現的,而圖像操作是在主窗口類中實現的,我的方法是在主窗口類中使用定時器,定時間隔假設為200ms,定時時間到時獲取ImgGraphicsView部件對象的成員變量值(將鼠標左鍵按下是坐標和鼠標移動時的坐標均定義為ImgGraphicsView類成員,其值隨着鼠標事件而變化)。就可以只帶鼠標此時的坐標點與鼠標按下時的坐標點,分別對X和Y軸做差,求出鼠標在X和Y軸上的移動距離,該距離就是圖像該移動的距離,然后改變當前ImgGraphicsView對象中的滑動條的值即可實現圖像的滑動。
要注意的是,鼠標左鍵按下時,x2=x1,y2=y1,保持x2和y2的更新,防止鼠標不移動定時時間到了圖像還是滑動了(因為x2,y2還是原值)。此外,鼠標釋放時標識符還原,x1=x2,y1=y2。
代碼就不貼了,理解上上述原理之后,就很容以寫出源代碼了,關鍵是實現的方法原理。下面是設置滑動條的值的方法:
1 int x=ui.graphicsView->horizontalScrollBar()->value();
2 int y=ui.graphicsView->verticalScrollBar()->value();
3 int dx=ui.graphicsView->x1-ui.graphicsView->x2;
4 int dy=ui.graphicsView->y1-ui.graphicsView->y2;
5 ui.graphicsView->horizontalScrollBar()->setValue(x+dx);
6 ui.graphicsView->verticalScrollBar()->setValue(y+dy);