Leo
Leo

Reputation: 1139

Subclassing QGraphicsView, custom mouse events

I'm subclassing QGraphicsView and what I'd like to do is: if the MidButton is pressed while the mouse is moving then we do as if we were using the regular QGraphicsView course of action but with the left button pressed which is sliding the image.

I tried coding it but it doesn't seems to work and I don't know why.

void MyQGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() == Qt::MidButton)
    {
        QMouseEvent event2(QEvent::MouseMove, event->pos(), Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
        QGraphicsView::mouseMoveEvent(&event2);
    }
}

Any help would be appreciated.

Edit: removed obvious error as pointed out by Anthony.

Upvotes: 0

Views: 2572

Answers (2)

Forest Darling
Forest Darling

Reputation: 311

What you seem to be aiming for is changing the "hand drag" mode's trigger button from the left button to the middle button.

While the event changing method works, it has some problems: when QGraphicsView is in "hand drag" mode it still propagates left clicks that don't drag afterward through to the scene/items. This means if you middle click and release without dragging, it'll think you left clicked and released without dragging. You'll have effectively triggered a left click onto the scene.

You can instead override the behavior of middle click to directly scroll the scene. This code was taken from QGraphicsView::mouseMoveEvent():

void View::mousePressEvent(QMouseEvent *event)
{
    _lastPos = event->pos();
    QGraphicsView::mousePressEvent(event);
}

void View::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons().testFlag(Qt::MidButton))
    {
        QScrollBar *hBar = horizontalScrollBar();
        QScrollBar *vBar = verticalScrollBar();
        QPoint delta = event->pos() - _lastPos;
        _lastPos = event->pos();
        hBar->setValue(hBar->value() + (isRightToLeft() ? delta.x() : -delta.x()));
        vBar->setValue(vBar->value() - delta.y());
    }
    QGraphicsView::mouseMoveEvent(event);
}

Upvotes: 0

Anthony
Anthony

Reputation: 8788

There are a few problems. First, the test condition should use testFlags rather than ==. Second, you were creating the event with Qt::MidButton and it should be Qt::LeftButton. Last, you also need to do a similar test for mousePressEvent (so that QGraphicsView can know to initiate the hand drag).

void mousePressEvent(QMouseEvent *event)
{
    if (event->buttons().testFlag(Qt::MidButton))
    {
        QMouseEvent event2(QEvent::MouseButtonPress, event->pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);

        // do default behavior as if you pressed the left button
        QGraphicsView::mousePressEvent(&event2);
    }
    else
    {
        QGraphicsView::mousePressEvent(event);
    }
}
void mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons().testFlag(Qt::MidButton))
    {
        QMouseEvent event2(QEvent::MouseMove, event->pos(), Qt::NoButton, Qt::LeftButton, Qt::NoModifier);

        // do default behavior as if you pressed the left button
        QGraphicsView::mouseMoveEvent(&event2);
    }
    else
    {
        QGraphicsView::mouseMoveEvent(event);
    }
}

Upvotes: 2

Related Questions