3
votes

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

2
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 onesCastilho
Sorry for not responding earlier. I'll check this tonight and let you know. Thank you.Alex

2 Answers

2
votes

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.

1
votes

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.