3

I can't figure out how to make centerOn() to move viewport around the item (or the item around the port, not sure which way it is).

The following code does work in main:

view.setDragMode(QGraphicsView::ScrollHandDrag);
view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view.setFrameStyle(QFrame::NoFrame);
view.showFullScreen();

QGraphicsPixmapItem *pmItem = new QGraphicsPixmapItem(pixMap);
scene.addItem(pmItem);

view.centerOn(QPointF(50,30));
view.show();
rc = qA.exec(); 

However, the centerOn() does nothing when I am trying to do the same from a paintEvent() of an overloaded QGraphicsView:

class MyView :: public QGraphicsView { ... }

void MyView::init(){
    ...
    setDragMode(QGraphicsView::ScrollHandDrag);
    setFrameStyle(QFrame::NoFrame);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    _scene.clear();
    setScene(&_scene);

    super::showNormal();

}


void MyView::paintEvent(QPaintEvent *aEvent){
    _scene.clear();
    QGraphicsPixmapItem *pmItem = new QGraphicsPixmapItem(pixMap);
    _scene.addItem(pmItem);
    centerOn(QPointF(50.0, 30.0));

    super::paintEvent(aEvent);
}

What do I miss? Thank you

Alex

Alex
  • 389
  • 2
  • 12
  • try to reimplement the function drawForeground instead of the paintEvent. That's the usual way you get to mess with things at the view. I'm guessing that the view is not drawn at the time paintEvent runs, and because of that the coordinates 30.0 and 50.0 are not valid ones – Castilho Oct 19 '12 at 02:12
  • Sorry for not responding earlier. I'll check this tonight and let you know. Thank you. – Alex Oct 19 '12 at 15:54

2 Answers2

2

You basically pull the rug under the paintEvent call.

QGraphicsView communicates with QGraphicsScene by way of signals and slots. The scene has no chance to notify the view that a new item is just added to it since the actual paintEvent is called right after the creation. There's no event loop process between the 2 steps. So the paintEvent call doesn't have it setup properly for the new item, let alone the centering change.

And once the painting is finished, the view is validated and thinks it's all painted. So the it'll never update the area of the new item.

Call centerOn outside of any painting or updating event.

Stephen Chu
  • 12,724
  • 1
  • 35
  • 46
  • Sorry for not responding earlier. Sounds reasonable, though the item is indeed updated and painted in the paintEvent. I'll check this tonight and let you know. Thank you. – Alex Oct 19 '12 at 15:55
  • Works fine from MouseMoveEvent. Thanks – Alex Oct 21 '12 at 23:55
1

I solved this problem by placing a high value on setSceneRect. Then I centralize the scene on an object or position.

example:

this->ui->graphicsView->setSceneRect (0,0,100000000, 100000000);
this->ui->graphicsView->centerOn(500,1030);

With the setSceneRect size GraphicsView does not work right.

Dmitry
  • 13,797
  • 6
  • 32
  • 48
Willyan
  • 123
  • 2
  • 7