PDA

View Full Version : strange QGraphicsView sizing behavior



tpf80
23rd January 2009, 03:13
I have created a main window with a QGraphicsView and worked it such that when the window is resized, the scene will remain in the window and scale itself to always fit within the QGraphicsView no matter what size it is. I used the following method to do this:




WindowScene::WindowScene(QWidget *parent) : QMainWindow(parent) {



setupUi(this);
database = db;

cview = new QGraphicsView;
cview->installEventFilter(this);//set event filter

setCentralWidget(cview);

cscene = new QGraphicsScene;
populateScene(); //put some junk in the scene for testing

cview->setScene(cscene);

createDockWindows();
//add dock widget to the side



}

bool WindowScene::eventFilter(QObject *o, QEvent *e) {
//process resize event of needed widget
if (o == cview && e->type() == QEvent::Resize) {
//rescale the scene to fit the view
cscene->views().first()->fitInView(cview->sceneRect().toRect(),Qt::KeepAspectRatio);
return true;
}
return QMainWindow::eventFilter(o, e);
}


This seems to work for the most part, but there is a strange issue where the scene will not show up when I drag the window in certain ways:

- If I expand the window to the side only, then the scene scaling works perfect
- If I expand the window to up and down only then the scene scaling works perfect.
- If I make the window smaller in the vertical and horizontal directions at the same time, the scene scales down.
- If I make the window larger vertically and horizontally at the same time, then the scene moves, centered with the window, but the viewport does not expand and the scaling stops short of where it should in order to fill the viewable area.

What might be causing this issue only when enlarging the window in both directions at same time? I have attached pictures so you can see what it is doing

seneca
23rd January 2009, 12:50
You might want to use qDebug() to trace what events are created during the resize.

tpf80
1st February 2009, 03:04
Using the following code as the event filter:


bool DialogScene::eventFilter(QObject *o, QEvent *e) {

qDebug()<<"Object:"<< o <<"Event: "<<e->type();

//process resize event of needed widget
if (o == calendarview && e->type() == QEvent::Resize) {
qDebug()<<"Should fire fitInView...";
//rescale the scene to fit the view
calendarscene->views().first()->fitInView(calendarscene->sceneRect(),Qt::KeepAspectRatio);

return true;
}
return QMainWindow::eventFilter(o, e);
}


I get the following results:
When I drag the window larger in any of the ways that will make the scene resize, the event firing sequence is as follows:



Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 14
Should fire fitInView...
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 12
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43 //fitInView happens here
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 14
Should fire fitInView...
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 12
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43 //fitInView happens here
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43


QEvent::Resize -> QEvent::Paint -> QEvent::MetaCall -> QEvent::MetaCall ...

The meta call happens over and over as I drag the boundries of the window. Commenting out the fitInView command causes the QEvent::MetaCall to not fire, so I assume QEvent::MetaCall is analogous to the fitInView command happening.

When the glitch happens as seen in the picture, dragging the window boundaries produces the following events:




Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 14
Should fire fitInView...
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 12
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 14
Should fire fitInView...
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 12
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 14
Should fire fitInView...
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 12
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 14
Should fire fitInView...
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 12



QEvent::Resize > QEvent::Paint > QEvent::Resize > QEvent::Paint... (over and over as I drag)

however as soon as I drag the window small enough to where the glitched area hits the edge of the view, then I get the following event sequence:



Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 14
Should fire fitInView...
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 12
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 76
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43 //fitInView happens here
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 12
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 14
Should fire fitInView...
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 12
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43 //fitInView happens here
Object: QGraphicsView(0xe42f10, name = "calendarview") Event: 43


QEvent::LayoutRequest > QEvent::Resize -> QEvent::Paint -> QEvent::MetaCall ...

so it seems that if I drag the window too far, then the QEvent::MetaCall AKA fitInView stops working, but as soon as it gets smaller and the QEvent::LayoutRequest fires, then everything returns to its proper operation.

It is also strange that the fitInView will not fire after its resized both vertical and horizontal at the same time, because the events show that the QEvent::Resize is triggering, and that the object that triggered it was "calendarview" so, there should be no reason why the if() statement does not evaluate to true and allow the fitInView command to work.

tpf80
1st February 2009, 20:04
I also tested the fitinview command by connecting a button to a slot so I could manually trigger it. What I found, was that the same results happen for the manual triggering of it. Maybe fitinView is working, but the "viewport" is not the same size as the QGraphicsView.

Is there a way to change the viewport size to match the QGraphicsView?