How to seamlessly place item into scene at specific location: Adding QGraphicsItem to scene always places it at 0,0
-
I'm trying to understand how to use QGraphicsScene and QGraphicsView and I am testing item placement with QGraphicsRectItem. I want to be able to call addRectItem and have the item added to a specific coordinate in the scene, for example (50,50). However, whenever I add the QRectF(50,50,20,20), it is always placed at (0,0). I can later move it by simply calling QGraphicsRectItem->setRect(QRectF(50,50,20,20)) on the returned pointer from addRectItem(). I don't want to do that, I want it placed exactly where it should go the first time.
According to the documentation for QGraphicsScene, it says "Items can be placed at any position on the scene". But in earlier paragraph, it says "...the items position is initialized to (0,0) in the scene".. So which is it?? And if the latter, how can I get these items to position correctly without the end-user seeing different objects being added to (0,0) and then moved quickly to their new locations?
Thanks.
-
You misunderstood.
scene->addRect(50,50,20,20)
does not add an item at position50,50
. It adds an item at position0,0
that draws a rectangle at50,50
, so your entire item bounding rectangle is0,0,70,70
.To add an item at
50,50
you would do:auto rectItem = new QGraphicsRectItem(0,0,20,20); rectItem->setPos(50,50); scene->addItem(rectItem);
item->setPos()
does not move the rectangle within the item, it moves the item itself.item->setRect()
on the other hand moves the rectangle inside the item and does not move the item itself.In other words rectangle coordinates are relative to the item origin point, not to
0,0
of the scene. -
Hi
Adding to @Chris-Kawa , its very important to read
https://doc.qt.io/qt-5/graphicsview.html
section The Graphics View Coordinate System / Item Coordinates
to understand how it works together. -
Brain hurt
@mrjj , I understand what you are saying about docs, I did read them before I asked here, but yes, I don't understand everything thus asking questions... :-)
There are what, three or four different coordinate systems at play here? Does anybody have any pictures that clearly show how these all tie together and how to place an object where you want it? I'm coming from a reference point of just dealing with basic painting where (0,0) is always the top-left point and not relative to anything. I'd go back to basic painting, but I've found my app concept really needs to use QGraphicsView and QGraphicsScene.
Oh, and by the way, scene->addRect(50,50,20,20) does not draw rectangle at 50,50 like you said, it is drawing it at 0,0, every time, and just to be clear, when I say (0,0), visually, I mean the top-left corner of the QGraphicsView. Maybe I should point out that I have QGraphicsView alignment in the form editor set for "AlignLeft, AlignTop". I changed it that way because I don't want everything centered in the view.
Pictures would really help here, not finding many pics in Qt docs that help explainl, if they are there, they are spread out in hidy-holes.
-
There are what, three or four different coordinate systems at play here?
Three. View coordinates, scene coordinates and item coordinates.
I'm coming from a reference point of just dealing with basic painting where (0,0) is always the top-left point
Then what you know translates directly to scene coordinates. On top of that is the view and scene can be moved freely in it so scene
0,0
and view0,0
are not the same. Since you set alignment the scene is moved inside the view so that the top left most item is in the corner. This moves0,0
of the scene outside of the view in your case.Oh, and by the way, scene->addRect(50,50,20,20) does not draw rectangle at 50,50 like you said, it is drawing it at 0,0, every time
It adds item to scene and in scene coordinates it has position
0,0
. If you print outitem->pos()
it will show0,0
as items are always placed in the scene. What you see is the result of alignment that causes the scene to be shifted in view coordinates.Pictures would really help here
Here you go. Note that those pictures show a view without alignment set, to show that scene and view
0,0
are not the same. The numbers are in scene coordinates.If you do
scene->addRect(50,50,20,20)
the result is this:
The dotted lines are the
0
axes of the scene. The red point is the item origin point and it's in0,0
of the scene. All item transformations are done using that point. You set it viaitem->setPos()
,item->setTransform()
and the likes. The red rectangle is the relative bounding box of the item. In case of aQGraphicsRectItem
it grows to encompass the actual black rectangle visible on the screen. That red rectangle is going to resize as you change the geometry of your rectangle viaitem->setRect()
. The black box is the rectangle drawn by the item. It is set to have an origin at50,50
in item's coordinates, so relative to the red point (item origin).Now, if you do
auto rectItem = new QGraphicsRectItem(0,0,20,20); rectItem->setPos(50,50); scene->addItem(rectItem);
the result is:
This creates an item, again in
0,0
in scene coordinates then moves it to50,50
. The item itself draws a black rectangle at0,0
in item coordinates.