0
votes

I have a subclass of QGraphicsView that should accept two kinds of mouse events: drag and drop for scrolling and simple clicks for item selection/highlight. So I use

setDragMode(QGraphicsView::ScrollHandDrag);

to enable scrolling the view with the "Hand". And I have a function like this:

void GraphView::mouseReleaseEvent(QMouseEvent* e)
{
    if (e->button() == Qt::LeftButton)
        emit leftClicked(mapToScene(e->pos()));
    else
        emit rightClicked(mapToScene(e->pos()));
    QGraphicsView::mouseReleaseEvent(e);
}

which creates signal whenever the user clicks on the scene.

However, the problem is: when I stop dragging and release the mouse button, the mouseReleaseEvent function is called, and if the cursor happens to be over some element of the scene, it will get highlighted. How can I changed the mouseReleaseEvent function so that the signals are created only if there was no previous drag of the mouse?

1

1 Answers

1
votes

If you use mousePress and mouseMove in combination with mouseRelease, then you can determine what mouse action the user just performed.

If you have mousePress then mouseRelease, then it must be a simple click. If you have mousePress, mouseMove, and then mouseRelease, then it must be a drag.

The Qt documentation contains an example of interpreting combinations of mouse events in action in a scribbling program. http://doc.qt.io/qt-4.8/qt-widgets-scribble-example.html

You can extend the principle to something like this:

private bool MyWidget::dragging = false;
private bool MyWidget::pressed = false;


void MyWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        pressed=true;
    }
    QGraphicsView::mousePressEvent(event)
}

void MyWidget::mouseMoveEvent(QMouseEvent *event)
{
    if ((event->buttons() & Qt::LeftButton) && pressed)
    {
        dragging=true;
    }
    QGraphicsView::mouseMoveEvent(event)
}

void MyWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton && pressed) {
        pressed = false;
        if (dragging)
        {
            dragging = false;
        }
        else
        {
            // plain mouse click
            // do something here
        }
    }
    QGraphicsView::mouseReleaseEvent(event)
}

Note that this does not address edge cases where a user's mouse action is performed only partially inside the widget. I must also admit that I am relatively new to Qt and have not yet used ScrollHandDrag, but this is how one would go about identifying a certain combination of mouse events.