1

I am working on a C++ application with Qt 4.8 as the GUI framework: A subclassed QGraphicsView rendering a subclassed QGraphicsScene containing one or more subclassed QGraphicsPixMapItem(s) in which I need to know the mouse cursor's relative pixel position.

Following How to show pixel position and color from a QGraphicsPixmapItem I subclass QGraphicsPixmapItem:

class MyGraphicsPixmapItem : public QObject, public QGraphicsPixmapItem
{
    Q_OBJECT
public:
    explicit MyGraphicsPixmapItem(QGraphicsItem *parent = 0);
signals:
public slots:
    void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
};

and implement constructor and handler:

MyGraphicsPixmapItem::MyGraphicsPixmapItem(QGraphicsItem *parent) : QGraphicsPixmapItem(parent)
{
    qDebug() << "constructor mygraphicspixmapitem";
    setCacheMode(NoCache);
    setAcceptHoverEvents(true);
    setFlag(QGraphicsItem::ItemIsSelectable,true);
}

void MyGraphicsPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
{
    QPointF mousePosition = event->pos(); 
    qDebug() << "mouseMoveEvent";
    qDebug() << mousePosition;
    QGraphicsPixmapItem::mouseMoveEvent(event);
}

I have also subclassed QGraphicsView and QGraphicsScene with respective mouseMoveEvent handlers that pass the event further down successfully:

void MyGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    qDebug() << "QGraphicsScene: mouseMoveEvent";
    QGraphicsScene::mouseMoveEvent(event);
}

However, although MyGraphicsView is configured with ...

setMouseTracking(true);
setInteractive(true);

... MyGraphicsPixmapItem only executes the mouseMoveEvent handler when being clicked or after setting it as grabber:

void MyGraphicsPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    qDebug() << QString("item clicked at: %1, %2").arg( event->pos().x()).arg( event->pos().y()  );
    event->accept();
    grabMouse();
}

I would like to know whether I am making a mistake or the solution given in the above-mentioned answer is flawed or incomplete. Further, I would like to know whether the mouseMoveEvent handler can be triggered without the QGraphicsPixmapItem being configured as 'grabber'. It is also acceptable if the configuration as grabber occurs automatically when the mouse first moves onto the item.

Here is a thread where a very similar problem seems to be related to the item's reference, but since I add the item to the scene like this:

thepixMapItem = new MyGraphicsPixmapItem();
scene->addItem(thepixMapItem);

I suppose this is not related.

Community
  • 1
  • 1
handle
  • 5,859
  • 3
  • 54
  • 82
  • Also, once the item is a grabber, it will even trigger the mouseMoveEvent if the mouse is outside the element. This is not intended for my purposes. – handle Aug 23 '12 at 10:56
  • Do you see the event if you override QGraphicsItem::sceneEvent? (i.e. see an event witrh the appropriate type field in this handler) – Pete Aug 23 '12 at 11:24
  • 1
    @Pete Yes, bool MyGraphicsPixmapItem::sceneEvent(QEvent *event) { qDebug() << "sceneEvent"; return QGraphicsItem::sceneEvent(event); } is called, but mouseMoveEvent does not get called. – handle Aug 23 '12 at 12:31
  • Maybe I should just use hoverMoveEvent. This pretty much does what I want! – handle Aug 23 '12 at 12:38

1 Answers1

1

The solution is to reimplement or filter the item's hoverMoveEvent, as mouseMoveEvent only triggers when receiving a mouse press:

If you do receive this event, you can be certain that this item also received a mouse press event, and that this item is the current mouse grabber.

handle
  • 5,859
  • 3
  • 54
  • 82