1. 程式人生 > 實用技巧 >Qt QGraphicsItem 滑鼠點選事件程式設計方法

Qt QGraphicsItem 滑鼠點選事件程式設計方法

功能需求,在QGraphicsView中顯示一張影象,如下圖,滑鼠點選圖片時返回圖片座標系內的畫素座標,但是點選邊上空白部分時不返回座標。

實現思路是子類化QGraphicsView,QGraphicsScene, QGraphicsPixmapItem,並重寫滑鼠點選事件函式mousePressEvent(QGraphicsSceneMouseEvent* event)。游標預設的樣式是手型樣式以便拖拽圖片。這裡我更改了滑鼠的樣式,變為十字型,並且關閉了拖拽圖片的功能。具體的實現方式見博文:QGraphicsView改變游標的樣式。

但是在重寫滑鼠點選事件函式時發現滑鼠點選事件在子類化後的QGraphicsScene中被響應,但是子類化後的QGraphicsPixmapItem無法響應。QGraphicsView的事件傳遞機制的順序是View->Scene->Item,也就是說事件被子類化的QGraphicsScene吞沒了,沒有傳遞到下一級的Item。


解決方案,在子類化的QGraphicsScene中重寫mousePressEvent()方法內部一定要要記得呼叫:

QGraphicsScene::mousePressEvent(event);

注意,要想返回影象座標系的位置,就需要在子類化的QGraphicsPixmapItem中呼叫scenePos()函式。即使放大影象,點選影象中相同位置也會返回相同座標結果。

關鍵程式碼如下:
子類化QGraphicsScene

 1 ImageScene::ImageScene(QObject* parent): QGraphicsScene(parent)
 2 {
 3 }
 4 
 5 ImageScene::~ImageScene()
6 { 7 } 8 9 void ImageScene::mousePressEvent(QGraphicsSceneMouseEvent* event) 10 { 11 QGraphicsScene::mousePressEvent(event); // 將點選事件向下傳遞到item中 12 }

子類化QGraphicsPixmapItem

 1 ImageItem::ImageItem(QGraphicsItem *parent): ImageItem(parent)
 2 {
 3 }
 4 
 5 ImageItem::ImageItem(const QPixmap& pixmap, QGraphicsItem* parent) : QGraphicsPixmapItem(pixmap, parent)
6 { 7 } 8 9 ImageItem::~ImageItem() 10 { 11 } 12 13 void ImageItem::mousePressEvent(QGraphicsSceneMouseEvent* event) 14 { 15 std::cout << "Item: (" << event->scenePos().x() << ", " << event->scenePos().y() << ')' << std::endl; 16 }

使用方法

1 ImageView* view = new ImageView(); // 子類化的QGraphicsView
2 ImageScene* scene = new ImageScene();
3 ImageItem* imageItem = new ImageItem(QPixmap::fromImage(image));
4 scene->addItem(imageItem);
5 view->setScene(scene);

如果在ImageScene的點選事件中呼叫scenePos(), 同時點選周圍白色邊框將會返回座標結果,此時座標系原點為顯示影象的左上角。換而言之,影象左側空白區域內座標的x均為負值,上方空白區域內座標的y均為負值,右側空白區域內座標的x大於影象寬度,下方空白區域內座標的y大於影象高度。