0

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.

Leo
  • 1,129
  • 4
  • 23
  • 38

2 Answers2

2

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);
    }
}
Anthony
  • 8,570
  • 3
  • 38
  • 46
  • That's my code at the moment: `if (event->buttons().testFlag(Qt::MidButton)) {QMouseEvent event2(QEvent::MouseMove, event->pos(), Qt::NoButton, Qt::LeftButton, Qt::NoModifier); QGraphicsView::mouseMoveEvent(&event2);}` It doesn't do what I'd like to do but the test seems good because it doesn't do what I've put in the `elif` after which I'm sure is working. – Leo Jun 21 '12 at 19:52
  • @Leo I had only tested it with rubber band drag. It turns out that with scroll hand drag, you need to reimplement mousePressEvent too. See edits. – Anthony Jun 21 '12 at 20:04
  • Thanks, it works now, the only problem is that I have to press a new button to make this behavior stop, just releasing the Midbutton isn't enough. – Leo Jun 21 '12 at 20:12
  • @Leo Then it seems you'll have to do the same for mouseReleaseEvent. I'll leave that one to you. :) – Anthony Jun 21 '12 at 20:22
  • Thanks, it worked! For anyone looking for the mouseReleaseEvent as it's a little different here comes: `if (!event->buttons().testFlag(Qt::MidButton)){QMouseEvent event2(QEvent::MouseButtonRelease, event->pos(), Qt::LeftButton, Qt::MidButton | Qt::RightButton, Qt::NoModifier); QGraphicsView::mouseReleaseEvent(&event2);}` – Leo Jun 22 '12 at 12:14
0

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);
}
oz123
  • 27,559
  • 27
  • 125
  • 187
Forest Darling
  • 311
  • 1
  • 3