Results 1 to 2 of 2

Thread: QGraphicsScene: adding QGraphicsProxyWidget moves others QGraphicsEllipseItem

  1. #1
    Join Date
    Sep 2021
    Posts
    1
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default QGraphicsScene: adding QGraphicsProxyWidget moves others QGraphicsEllipseItem

    Hi,

    Sorry for the silly question but I'm working with QGraphicsScene and I have "weird" behaviours that I don't understand at all.

    Basically I have a simple radar representation with a main "circle" and an icon which represent the North direction.

    So I have somthing like this:

    Qt Code:
    1. QGraphicsScene* l_scene = new QGraphicsScene(this);
    2. ui->radar_gw->setScene(l_scene);
    3. ui->radar_gw->setRenderHints(QPainter::Antialiasing);
    4.  
    5. m_main_offset = 2;
    6. m_north_space_px = 12;
    7.  
    8. m_radar_gui_diameter = ui->radar_gw->width()-(m_north_space_px*2)-m_main_offset;
    9. m_radar_gui_radius = m_radar_gui_diameter * 0.5;
    10.  
    11. //MAIN CIRCLE
    12. QGraphicsEllipseItem* l_radar_circle = new QGraphicsEllipseItem(0, 0, m_radar_gui_diameter, m_radar_gui_diameter);
    13. l_radar_circle->setPen(QPen(QColor(Qt::green), 2));
    14. l_scene->addItem(l_radar_circle);
    15.  
    16. //NORTH
    17. QPixmap l_north_pix(":/background/north.png");
    18. QLabel* l_north_lbl = new QLabel();
    19. l_north_lbl->setAutoFillBackground(false);
    20. l_north_lbl->setPixmap(l_north_pix.scaled(m_north_space_px, m_north_space_px, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
    21. QGraphicsProxyWidget* l_north_widget = l_scene->addWidget(l_north_lbl);
    22. l_north_widget->setPos(m_radar_gui_radius - m_north_space_px*0.5, 0);
    To copy to clipboard, switch view to plain text mode 

    Basically this code display something like this:

    1.jpg

    There is a first question:

    Qt Code:
    1. l_north_widget->setPos(m_radar_gui_radius - m_north_space_px*0.5, 0);
    To copy to clipboard, switch view to plain text mode 

    This setPos is relative to the QGraphicsEllipseItem (l_radar_circle) dimensions and NOT to the main QGraphicsView container. Why?!? l_radar_circle is added to l_scene (QGraphicsScene) not to the QGraphicsEllipseItem. Where I'm in wrong?

    -----

    As you can see in the previous image, I've left the space to show the North icon outside the circle (because the North icon can move around the main circle).
    So, I've tried to move up the North icon like this:

    Qt Code:
    1. l_north_widget->setPos(m_radar_gui_radius - m_north_space_px*0.5, -m_north_space_px-m_main_offset);
    To copy to clipboard, switch view to plain text mode 

    And this is the result:

    2.jpg

    The main l_radar_circle as moved down, like the l_north_widget interacts with the l_radar_circle (and then there is not enough space at the bottom of l_radar_circle). I don't want this behaviour, just as I don't want the previous case where the North widget is relative to the main circle item.

    Can you address me a way to achieve a correct beahviour? Basically, I need a method to freely draw shapes and textures without "shadow" layout and "weird" reparenting. I have to go with OpenGL directly?

    Many thanks, bye
    Last edited by Doxy82; 9th September 2021 at 22:40.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,063
    Thanks
    286
    Thanked 831 Times in 818 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: QGraphicsScene: adding QGraphicsProxyWidget moves others QGraphicsEllipseItem

    The origin for the QGraphicsEllipseItem is in the center of the ellipse. When you create this, the first two arguments are the position of the circle with respect to its parent, which in this case is the scene. So you are telling the scene that the circle's center goes at the scene's origin.

    When you put the scene into a QGraphicsView, the view will automatically center the scene in the view and size it so the view contains the scene's bounding box. So if all you have in the scene is the circle, the view's top left scene coordinate is (-radius, -radius), the circle fills the view, and sits at the view's center.

    When you create the North symbol, the coordinates are also with respect to the scene since the symbol has no parent. So now you have a circle at (0, 0) and a symbol at (radius - spacing/2, 0). When this is put into the view, the view still has the scene's (-radius, -radius) as the top left corner, and the circle's center appears to be at the center of view (which it is) because the view adds (radius, radius) to the coordinates as it scales and centers the scene.

    The origin (0, 0) coordinates for the QGraphicsProxyWidget are at the top left corner of the proxy, not the center as for the circle. So setting the position to (radius + spacing / 2, 0) means that the x dimension of the proxy will be centered on the circle's center, and the top will be at the top of the circle, in scene coordinates.

    That's exactly what you get in your first screenshot.

    In the second screenshot, you have moved the top of the proxy widget up (negative Y is up) by the size of the proxy plus some offset. Now the bounding box of the scene is larger, so when the view scales and centers the scene, the top left corner of the view corresponds to the scene coordinates (-radius, -radius - spacing - offset), and the size of the scene displayed in the view goes from this top left scene coordinate to (+radius, +radius) on the bottom right.

    If the size of your view does not change, then this makes the circle smaller and it appears to be "pushed down" in the view because of the view's scaling and translation of the scene.

    The important thing to remember about the Graphics / View architecture is that all coordinates are defined relative to the parent of each item in the scene, not the view. If an item is a top-level item in the scene, then its coordinates are scene coordinates. If an item is a child of another item, then its position is relative to the origin of the parent item.

    If you make your N symbol a child of the circle, and give it the position (0,0), then the top left of the symbol would sit at the circle's center (because the symbol's origin (0,0) is the top left of the symbol, while the circle's origin is at its center. If you move the circle to a new position in the scene, the N symbol will move with it, since it is a child of the circle.

    You can control what part of the scene is displayed in the view and how the scaling and translation works by using one of the QGraphicsView::setSceneRect() or QGraphicsView::fitInView() methods.

    By the way, you do know that there is a QGraphicsPixmapItem that can directly hold your JPG without a proxy, right?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Replies: 5
    Last Post: 3rd April 2019, 18:34
  2. Replies: 1
    Last Post: 9th September 2016, 09:46
  3. Screenshot of QGraphicsScene with QGraphicsProxyWidget
    By anirudh123 in forum Qt Programming
    Replies: 2
    Last Post: 14th July 2016, 12:56
  4. Replies: 8
    Last Post: 9th July 2010, 01:37
  5. Adding QGraphicsProxyWidget items into QGraphicsScene
    By yagabey in forum Qt Programming
    Replies: 3
    Last Post: 21st November 2008, 07:33

Tags for this Thread

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.