Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-interest Archive, May 2007
Re: QGraphicsRectItem resize problem QT4.3


Message 1 in thread

Jeff Lacki wrote:

>Sorry for such a basic question, I have a QGraphicsRectItem
>and I want to resize it.  When I do, its position is way
>off.  I thought all I had to do was use mapToScene() or
>mapFromScene() (I always get them backwards), but this didnt
>solve my issue.  My width and height are fine, just its
>position is wrong.
>  
>
An update and question on this topic.  I found that the issue is that Im 
having a problem
finding the X,Y coordinate in QGraphicsView/Scene.  Im trying to convert 
the logical?
coordinates to scene coordinates.  I tried using mapToScene, 
mapFromScene and I
even saw the transform class and thought that was the key, so I tried 
transform().map()
with no luck.

Can someone tell me how to get my coordinates to and from the 
QGraphicsScene?
Im thoroughly confused.  I store the coordinates of my rectangles in my 
own vector
of QRectF's, and create seperate QGraphicRectItems, so if I modify the 
original
QRectF, I need to update each rect's x,y on the screen.  This is what I 
cant seem to
figure out.

Any help is greatly appreciated.
Jeff


--
 [ signature omitted ] 

Message 2 in thread

Jeff Lacki wrote:

> Can someone tell me how to get my coordinates to and from the
> QGraphicsScene?  Im thoroughly confused.  I store the coordinates of
> my rectangles in my own vector of QRectF's, and create seperate
> QGraphicRectItems, so if I modify the original QRectF, I need to 
> update each rect's x,y on the screen.  This is what I cant seem to
> figure out.
> Any help is greatly appreciated.
> Jeff

Well, obviously, to reposition a QGraphicsItem, you use its setPos() method. 
The problem seems to be in the parameters you are using.

The key thing to remember is that you specify an item's position using the
coordinate system established by its parent.  The boundingRect() function
is what specifies the coordinate system to be used by the children of that
item.

Let's look at an example.  Let's say you have an ItemA (at the top level)
positioned at QPoint(100,200).  Since this is a top level item, these
coordinates are relative to those defined by the QGraphicsScene.  Further,
let's say that ItemA.boundingRect() returns QRect(-50,-50,100,100).  This
means that QPoint(-50,-50) within ItemA is the same as QPoint(100,200)
within the QGraphicsScene.  It's very important that you understand why, so
work on this until it is very clear.

Now add an ItemB as a child of ItemA, and do a ItemB.setPos(0,0).  Since the
coordinate system for children of ItemA use QRect(-50,-50,100,100), the
upper left hand corner of ItemB will be placed at the center of ItemA's
boundingRect(), 50 points down and 50 more to the right.  Its simple math
to learn that the equivalent coordinates within the QGraphicsScene are
QPoint(150,250).  If you now add ItemC as a child of ItemB, its position
will be defined by ItemB.boundingRect().  

The coordinate system of a QGraphicsItem is established by (is relative to)
the boundingRect() of the item's parent.  Throw rotation, scaling, and
shear into the picture and the math gets somewhat more complicated, but it
still works as above.

Hope this helps...

--
 [ signature omitted ] 

Message 3 in thread

Larry Bristol wrote:

>The key thing to remember is that you specify an item's position using the
>coordinate system established by its parent.  The boundingRect() function
>is what specifies the coordinate system to be used by the children of that
>item.
>  
>
Thanks Larry for the in-depth info.  This makes sense.  I can see how 
you would get an existing
boudingRect() for each level.  The problem I have is that the item is 
already at the top level.
In in my code, I change the logical coordinates to a new X,Y, so I dont 
know how to translate
a logical coordinate to the scene coordinate I think?  Im assuming what 
you are saying is that
by using boundingRect() I can find his logical coordinates...but thats 
not what I need in this case.

Maybe Im still confused?

Very simply put, I do something like this:

origX = 10;
origY = 10;
QRectF rect(origX, origY,20,20);
create QGraphicsRectItem(rect)

dialog box to possibly add more rects, change their width/height
W = newW;
H = new H;
if create additional rect(s)
{
    QRectF newrect(origX + W, origY, W, H);
    create QGraphicsRectItem(newrect);
}

loop over QGraphicRectItem ptr rects and update:
setRect(0,0, W, H);
setPos(??????)

Jeff


--
 [ signature omitted ] 

Message 4 in thread

Jeff Lacki wrote:
> Thanks Larry for the in-depth info.  This makes sense.  I can see how
> you would get an existing boudingRect() for each level.  The problem I
> have is that the item is already at the top level.
> In in my code, I change the logical coordinates to a new X,Y, so I dont
> know how to translate a logical coordinate to the scene coordinate I
> think?  Im assuming what you are saying is that by using boundingRect()
> I can find his logical coordinates...but thats not what I need in this
> case. 
> Maybe Im still confused?
> Very simply put, I do something like this:
> 
> origX = 10;
> origY = 10;
> QRectF rect(origX, origY,20,20);
> create QGraphicsRectItem(rect) 
> dialog box to possibly add more rects, change their width/height 
> W = newW;
> H = new H;
> if create additional rect(s)
> {
>     QRectF newrect(origX + W, origY, W, H);
>     create QGraphicsRectItem(newrect);
> }
> 
> loop over QGraphicRectItem ptr rects and update:
> setRect(0,0, W, H);
> setPos(??????)

Hi, Jeff.  Sorry to not respond to your question sooner.  Thursday is always
a brutal day for me.

I'm not quite sure I follow the question above, but I'll try to explain what
I would expect to see.  I have not used QGraphicsRectItem myself, so I
might not be interpretting the parameters correctly, but here goes.

The parameters (10,10,20,20) for the first QGraphicsRectItem define that
item's boundingRect().  Other factors, such as the current pen width, will
make it slightly larger than 20x20 once it is actually rendered within a
scene.  It is a top level item, and (apparently) is not associated with any
QGraphicsScene.

If we assume W=22 and H=33, for an example, the second QGraphicsRectItem
would have a boundingRect() something like QRect(32,10,22,33).  It also has
no parent, and is not associated with any QGraphicsScene.

In the loop, the setRect() function is used to redefine the rectangle for
some reason.  All this does is redefine its boundingRect().  Changing the x
and y parameters would generally affect only children the rectangle might
have; changing the w and h would, of course, change the size of the
rectangle once it is actually rendered within a scene.

The call to setPos() with the unspecified parameters would be used to
actually position a rectangle within something.  That something could be
either (1) the item's parent (if it had one), or (2) the scene (if it had
one).  But since it has neither, it would do nothing useful that I can see.

Perhaps I see the source of your confusion.  Apparently, you are thinking
that the x and y parameters to the constructor (and to setRect) are
*positioning* the RectItem.  I do not think this is the case!  They are
simply defining the origin for the item's boundingRect().  You need to use
setPos() to establish its position.

My suggestion is that you associate each item with the scene as soon as
practical.  You can do this either on the constructor, or with the
QGraphicsScene::addItem() method.  You might want to take a look at the
addRect() method to see if it might be useful to you.

Regards,
Larry

--
 [ signature omitted ] 

Message 5 in thread

Larry Bristol wrote:

>
>Hi, Jeff.  Sorry to not respond to your question sooner.  Thursday is always
>a brutal day for me.
>  
>
No problem Larry, everyday is brutal for me, I can relate.  Im the sole 
developer here.

>I'm not quite sure I follow the question above, but I'll try to explain what
>I would expect to see.  I have not used QGraphicsRectItem myself, so I
>might not be interpretting the parameters correctly, but here goes.
>
>The parameters (10,10,20,20) for the first QGraphicsRectItem define that
>item's boundingRect().  Other factors, such as the current pen width, will
>make it slightly larger than 20x20 once it is actually rendered within a
>scene.  It is a top level item, and (apparently) is not associated with any
>QGraphicsScene.
>
>If we assume W=22 and H=33, for an example, the second QGraphicsRectItem
>would have a boundingRect() something like QRect(32,10,22,33).  It also has
>no parent, and is not associated with any QGraphicsScene.
>
>In the loop, the setRect() function is used to redefine the rectangle for
>some reason.  All this does is redefine its boundingRect().  Changing the x
>and y parameters would generally affect only children the rectangle might
>have; changing the w and h would, of course, change the size of the
>rectangle once it is actually rendered within a scene.
>
>The call to setPos() with the unspecified parameters would be used to
>actually position a rectangle within something.  That something could be
>either (1) the item's parent (if it had one), or (2) the scene (if it had
>one).  But since it has neither, it would do nothing useful that I can see.
>
>Perhaps I see the source of your confusion.  Apparently, you are thinking
>that the x and y parameters to the constructor (and to setRect) are
>*positioning* the RectItem.  I do not think this is the case!  They are
>simply defining the origin for the item's boundingRect().  You need to use
>setPos() to establish its position.
>
>My suggestion is that you associate each item with the scene as soon as
>practical.  You can do this either on the constructor, or with the
>QGraphicsScene::addItem() method.  You might want to take a look at the
>addRect() method to see if it might be useful to you.
>
>  
>
Im sorry Larry, I should have said, my parent is QGraphicsScene inside a 
QGraphicsView (Qt4.3).  I just meant
that the top most parent is the object I was dealing with, so sorry for 
that confusion.  The sole issue for me
is what to setPos() to.  It seems so trivial, and it probably is.  Just 
cant seem to find the right method call
to get what I want.

Thanks again for your help.
Jeff


--
 [ signature omitted ] 

Message 6 in thread

Jeff Lacki wrote:
> The sole issue for me is what to setPos() to.  It seems so trivial, and 
> it probably is.  Just cant seem to find the right method call to get what
> I want. 

I went through that same sort of thing, and I'm still not completely
comfortable with it all.  One thing I did that seemed to help was that I
quickly abandoned the use of all of the QGraphicsXxxxItem classes, and
started deriving my own from QGraphicsItem.  This forces you to write your
own boundingRect() and paint() functions.  The first thing I do is draw a
rectangle (QPainter::drawRect()) around the edge of the bounding rectangle
(there's a useful example in the doc for the QGraphicsItem class).  This
way, I can actually see what happens as I reposition, resize, and generally
fiddle around with the item.  When it seems to be working OK, I simply
remove the drawRect() call (assuming I don't want a visible rectangle
around the item in the first place).

--
 [ signature omitted ]