Results 1 to 16 of 16

Thread: QGraphicsItem coordinates, again

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,233
    Thanks
    303
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default QGraphicsItem coordinates, again

    Still struggling to understand coordinate mappings.

    I have a QGraphicsItem-derived object that uses a logical X coordinate range of 0.0 - 1000.0 arbitrary units. Inside it, it creates a QGraphicsSimpleTextItem, which of course uses pixels as its logical coordinate system. I've also set ItemIgnoresTransformations on the text so it doesn't become invisibly small in the view.

    I want to put the center().x() of the text item at the center().x() of my graphics item, but my graphics item doesn't know anything about pixels.

    So, how to do this? The scene that contains this might be displayed in multiple views of different sizes, so I can't just position the label with respect to one view.

    Thanks for any help.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QGraphicsItem coordinates, again

    boundingRect of the text item should be defined relative to the center of the item and not its top-left corner as it is by default. Then use setPos(), passing boundingRect().center() of the parent item. Alternatively use mapFrom* and mapTo* to map the coordinates between items.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,233
    Thanks
    303
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QGraphicsItem coordinates, again

    If I call boundingRect() on the QGraphicsSimpleTextItem, I get a rect of (x = 0, y = 0, w = 86, h = 19) for the font and text string I am using. That tells me that the text object's origin is at the top left.

    If the origin was at the center, I should get a rect of (x = -43, y = -9.5, w = 86, h = 19), right?

    If I call textItem->setPos( bounds.center() ) (where "bounds" is the bounding rect of my object that contains the text), then the top left corner of the simple text item is at the center of my object's rect, not the text's center.

    So, back to the beginning: it seems like I have an impossible situation. I have a graphics object that can be scaled by the scene, but it contains a text object that is set to ignore the scaling transformation. So how can I determine where the center of the text object is with respect to the center of my graphics object?

    Is there a different way to do this? Would it be better to make my graphics object and the text object siblings instead of parent and child?

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QGraphicsItem coordinates, again

    Quote Originally Posted by d_stranz View Post
    If I call boundingRect() on the QGraphicsSimpleTextItem, I get a rect of (x = 0, y = 0, w = 86, h = 19) for the font and text string I am using. That tells me that the text object's origin is at the top left.

    If the origin was at the center, I should get a rect of (x = -43, y = -9.5, w = 86, h = 19), right?
    Yes.

    If I call textItem->setPos( bounds.center() ) (where "bounds" is the bounding rect of my object that contains the text), then the top left corner of the simple text item is at the center of my object's rect, not the text's center.
    It's not what I told you to do. You need to redefine boundingRect() for the text item by subclassing it or wrapping it into another item with origin in the centre of the item.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,233
    Thanks
    303
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QGraphicsItem coordinates, again

    Quote Originally Posted by wysota View Post
    It's not what I told you to do. You need to redefine boundingRect() for the text item by subclassing it or wrapping it into another item with origin in the centre of the item.
    I am not trying to argue, just understand. Wrapping or subclassing the text item doesn't help, because it still has an internal coordinate system in pixels.

    So, I am almost at a solution. I turned off ItemIgnoresTransformations for the QGraphicsSimpleTextItem instance. So, now when I obtain the text width and call textItem->mapRectToParent( textItem->boundingRect() ), I get a rect in centimeters. I can center the text because I have apples + apples.

    To prevent it from scaling, I set a scale transform on the text item that is the inverse of the centimeter item's scale (i.e. 1 / sx, 1 / sy). So now the text remains the same size regardless of the scale of the centimeter item.

    A few more tweaks, and I think I will have something that behaves the way I want it to.

    Thank you for the help.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QGraphicsItem coordinates, again

    Quote Originally Posted by d_stranz View Post
    Wrapping or subclassing the text item doesn't help, because it still has an internal coordinate system in pixels.
    I don't see how this matters.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. The following user says thank you to wysota for this useful post:

    d_stranz (18th June 2011)

  8. #7
    Join Date
    Jun 2011
    Location
    Finland
    Posts
    164
    Thanks
    1
    Thanked 26 Times in 26 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Maemo/MeeGo

    Default Re: QGraphicsItem coordinates, again

    lets assume your derived graphicsItem draws a circle, so that's what you have to do:

    *boundingRect() must return QRectF(-width/2, -height/2, width, height);
    *in paint(..) you draw you circle, so it's center is at 0,0. painter->drawArc(-width/2, -height/2, width, height, 0, 5760);

    then your derived textitem, must be drawn also in the middle:

    *in boundingRect() use QFontMetrics do determine the bounding rectangle of the text. Then adjust that rect like this: rect.adjust(-rect.width()/2,-rect.height()/2,-rect.width()/2,-rect.height()/2); and then return it
    *in paint(..) you draw your text in the rectangle calculated the same way as you have done it in boundingRect() method. Of course you can do the calculation elsewhere, so you don't do it over and over again.

  9. The following user says thank you to Rachol for this useful post:

    d_stranz (18th June 2011)

  10. #8
    Join Date
    Apr 2010
    Posts
    769
    Thanks
    1
    Thanked 94 Times in 86 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QGraphicsItem coordinates, again

    1) Determine the center of the text item in local coordinates.

    2) setTransform() the item to shift its origin to the center.

    3) Do the same with your parent graphicsItem.

    Now, everyone is working with a center-based coordinate system.

    You can do the same with scenes.

  11. The following user says thank you to SixDegrees for this useful post:

    d_stranz (18th June 2011)

  12. #9
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,233
    Thanks
    303
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QGraphicsItem coordinates, again

    Quote Originally Posted by SixDegrees View Post
    1) Determine the center of the text item in local coordinates.

    2) setTransform() the item to shift its origin to the center.

    3) Do the same with your parent graphicsItem.

    Now, everyone is working with a center-based coordinate system.

    You can do the same with scenes.
    OK, got it. As long as everyone is in a center-based coordinate system, then I can position things with respect to their centers without worrying about transformations between pixels and a non-pixel logical coordinate system.

    Why is it that QGraphicsSimpleTextItem is different from all other QGraphicsItem classes? If it also had its origin at the center, then none of this discussion would have been necessary.

    Thanks to everyone for the help.

    Quote Originally Posted by wysota View Post
    I don't see how this matters.
    You're right, it doesn't. Being able to align centers is all that matters.

  13. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QGraphicsItem coordinates, again

    Quote Originally Posted by d_stranz View Post
    Why is it that QGraphicsSimpleTextItem is different from all other QGraphicsItem classes? If it also had its origin at the center, then none of this discussion would have been necessary.
    None of the standard item classes have the origin at the centre.

    And while we're at it, it is not required that all items are to be center-aligned. It is only required that the text item is to have its origin at its centre if you want to anchor the centre of the item to something else. If you wanted to align the bottom right corner, then the bottom right corner should be in the item origin. This is all only to make calculations easier since then the offset between the anchor and the origin is always 0, regardless of the scale or unit interpretation (0*anything = 0).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  14. #11
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,233
    Thanks
    303
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QGraphicsItem coordinates, again

    Quote Originally Posted by wysota View Post
    And while we're at it, it is not required that all items are to be center-aligned. It is only required that the text item is to have its origin at its centre if you want to anchor the centre of the item to something else. If you wanted to align the bottom right corner, then the bottom right corner should be in the item origin. This is all only to make calculations easier since then the offset between the anchor and the origin is always 0, regardless of the scale or unit interpretation (0*anything = 0).
    In that case, we're back to the original question again. If all of the objects have their origins at the center, then it doesn't matter what logical coordinates they use. One could be in pixels, another in cm, and a third in cubits. If you want to put a child item at the center of its parent, then you just call child->setPos() with the parent's center point.

    This is not true if the child item does not have its origin at the center, and uses a different basis unit from its parent. If the origin is at the top left or bottom left (or anywhere except the center), you then need to know how to convert pixels into cubits so you can center the pixel-based child in the cubit-based rect.

    This conversion is different for every view, because the scaling from view coordinates (pixels) to scene coordinates (cubits) is different for every view, but the conversion from view pixels to text pixels is fixed and constant. So if I want my text at some fixed location in the scene, I do not see any way to assign a position to the text so that it remains at the same relative location in every view of the scene.

    What am I missing here that all of you seem to understand but I don't?

Similar Threads

  1. Replies: 7
    Last Post: 29th November 2010, 19:20
  2. Replies: 7
    Last Post: 21st March 2010, 03:11
  3. Replies: 4
    Last Post: 18th March 2010, 10:11
  4. Replies: 0
    Last Post: 24th November 2008, 08:52
  5. Replies: 1
    Last Post: 26th September 2006, 05:38

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.