QGraphicsView: Disable automatic scrolling
Asked Answered
M

6

7

I want to have a QGraphicsView that never scrolls automatically.

Similar: Basically, my question is identical to http://developer.qt.nokia.com/forums/viewthread/2220 , but that thread didn't receive an answer.

What I have tried so far:

  • Within showEvent() and resizeEvent(), I do ui->graphicsView->fitInView(...), which works fine as long as items do not overshoot the screen-rectangle
  • I've also tried manipulating the view transform, but apart from scaling it's coefficients never change, so this was fruitless, too
  • Diabling scroll bar appearance does not help, too

See also http://doc.qt.io/qt-4.8/qgraphicsview.html.

M answered 14/1, 2011 at 9:42 Comment(0)
M
4

I found a solution (don't hesitate to post your alternatives :) ), still I thought this answer might be helpful as I struggled on google and documentations for like 15 hours.

The key is to not only call fitInView(), but also setSceneRect(). This did it for me (replace FooBar with your own class name):

void FooBar::resizeEvent(QResizeEvent *) {
        fitView();
}

void FooBar::showEvent(QShowEvent *) {
        fitView();
}

void FooBar::fitView() {
        const QRectF rect = QRectF(-0.5,-0.5, 1, 1);
        ui->graphicsView->fitInView(rect,
                                    Qt::KeepAspectRatio);
        ui->graphicsView->setSceneRect(rect);
}
M answered 14/1, 2011 at 9:45 Comment(0)
S
9

My solution is a bit sketchy but I think it's pretty intuitive: If you don't want the QGraphicsView to ever scroll your stuff, override the virtual method scrollContentsBy.

void QGraphicsViewDerived::scrollContentsBy(int, int)
{
    //don't do anything hah!
}
Schaeffer answered 25/2, 2011 at 18:31 Comment(1)
I'm using setTransformationAnchor(QGraphicsView::AnchorUnderMouse);. This solution breaks zooming under the mouse.Hottentot
M
4

I found a solution (don't hesitate to post your alternatives :) ), still I thought this answer might be helpful as I struggled on google and documentations for like 15 hours.

The key is to not only call fitInView(), but also setSceneRect(). This did it for me (replace FooBar with your own class name):

void FooBar::resizeEvent(QResizeEvent *) {
        fitView();
}

void FooBar::showEvent(QShowEvent *) {
        fitView();
}

void FooBar::fitView() {
        const QRectF rect = QRectF(-0.5,-0.5, 1, 1);
        ui->graphicsView->fitInView(rect,
                                    Qt::KeepAspectRatio);
        ui->graphicsView->setSceneRect(rect);
}
M answered 14/1, 2011 at 9:45 Comment(0)
A
2

Sure, the solution with setSceneRect() is right, but when there is a lot of legacy code, it can be too expensive.

I tried also scrollContentsBy(), but it affected scene positioning in my case.

So I came to the following solution:

class GraphicsView : public QGraphicsView
{
protected:
    void wheelEvent(QWheelEvent*) override {}
    void keyPressEvent(QKeyEvent* e) override { QWidget::keyPressEvent(e); }
};
Anesthetize answered 14/8, 2018 at 7:17 Comment(0)
L
1

I found the perfect solution, by calling

QGraphicsView::setSceneRect(yourScene->sceneRect()) 

in the constructor of your view, the automatic scrolling behavior is stopped.

Larue answered 18/8, 2016 at 14:31 Comment(0)
P
0

view->setDragMode(QGraphicsView::NoDrag); did the trick for me.

The solution from anonvt also worked except that it interfered with the refreshing of the scene.

Pris answered 28/11, 2014 at 11:42 Comment(0)
W
-1

Another simple solution, if no interactivity is needed, is to disable the QGraphicsView:

view->setEnabled(false);

This will also prevent it from scrolling, however it also won't receive mouse or keyboard events anymore.

Whaley answered 8/6, 2014 at 4:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.