PDA

View Full Version : QGraphicsView coordinates system problem



Oximoron
27th April 2010, 11:07
Hi,

This is a great site, and I am glad to have found it!
I hope someone could help me with the following problem:

I am trying to figure out how QGraphicsView coordinate system works, based on the docs, and it doesn't match up to what I see as a result of the code I write.
Here are the points that I don't understand, and below is the code for my example that shows the problems.
I will try to post the resulting screenshot for that code.

The first point is, item coordinates.
The docs state that:

Items live in their own local coordinate system. Their coordinates are usually centered around its center point (0, 0), and this is also the center for all transformations.
and


At item's position is the coordinate of the item's center point in its parent's coordinate system; sometimes referred to as parent coordinates. The scene is in this sense regarded as all parent-less items' "parent". Top level items' position are in scene coordinates.

However, if I add an item to a parent item, and do setPos(0,0) the added item appears at the top left corner, instead of being at the middle as the docs say.
(As can be seen in the screen shot)

Another issue is the position of a top level item in the scene.
In my code I set a sceneRect(), so the scene should NOT be unlimited.
In addition, if I add an Item to it, and do setPos(0,0) the item is neither at the top left, nor is it in the middle.
It seems that the scene shows more then its sceneRect().
If I ask the position of the item, it returns correct (0,0) but visually, it is at some distance from the rims of the scene.
If I want a scene which has its left upper corner as 0,0 and bottom right corner as 500,500, what should I do?
setSceneRect() is not giving that result (as can be seen in screen shot.)

The last question is about the scene rect.
Since I am setting the scene rect, I expect the scene to have a fixed size.
However, if I resize my view, the scene resizes to fill it, even though the setSceneRect() was set.

So what am I missing here?

Here is my code.
It creates a basic set of QGraphicView elements.
I am placing 2 QGraphicsRectItems.
The red one (rect1) is the top level item, the blue one (rect2) is a child item of rect1.
I gave the scene a green background to see if it resizes in the view, and it does.



int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
QHBoxLayout layout;
w.setLayout(&layout);
w.setGeometry(0,0,500,500);

QGraphicsScene scene;
scene.setBackgroundBrush(QBrush(Qt::green));
scene.setSceneRect(0,0,450,450);

QGraphicsView view(&scene,&w);

QGraphicsRectItem rect1(0,0,100,100);
rect1.setBrush(QBrush(Qt::red));

QGraphicsRectItem rect2(0,0,50,50,&rect1);
rect2.setBrush(QBrush(Qt::blue));

//Place items in scene
scene.addItem(&rect1);
rect1.setPos(0,0);
rect2.setPos(0,0);

//Put it all togeather
layout.addWidget(&view);
w.show();
return a.exec();
}


4551

Thanks!

spud
27th April 2010, 17:26
Hi,
However, if I add an item to a parent item, and do setPos(0,0) the added item appears at the top left corner, instead of being at the middle as the docs say.
(As can be seen in the screen shot)

The key word here is usually. When you pass a rectangle, you pass its origin with it.



// This is a centered rectangle:
QGraphicsRectItem rect1(-50,-50,100,100);



Another issue is the position of a top level item in the scene.
In my code I set a sceneRect(), so the scene should NOT be unlimited.
In addition, if I add an Item to it, and do setPos(0,0) the item is neither at the top left, nor is it in the middle.
It seems that the scene shows more then its sceneRect().
If I ask the position of the item, it returns correct (0,0) but visually, it is at some distance from the rims of the scene.
If I want a scene which has its left upper corner as 0,0 and bottom right corner as 500,500, what should I do?
setSceneRect() is not giving that result (as can be seen in screen shot.)

Use this class to show you the true extents of the scene rect:

struct GraphicsScene : public QGraphicsScene
{
void drawBackground(QPainter *painter, const QRectF &rect)
{
painter->fillRect(sceneRect()&rect, backgroundBrush());
}
};

The scene rect isn't as hard a constraint as you might think. You can even move items outside of the scene rect, and they will still be rendered if the QGraphicsView is big enough.




The last question is about the scene rect.
Since I am setting the scene rect, I expect the scene to have a fixed size.
However, if I resize my view, the scene resizes to fill it, even though the setSceneRect() was set.

So what am I missing here?

I hope it is clear now that the scene isn't resizing. If you want your QGraphicsView to show the scene and nothing more.
you could call setMaximumSize() on it.