Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qgraphicsscene setParentItem update childrens position?
QtWS25 Last Chance

Qgraphicsscene setParentItem update childrens position?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qt c++parent & childqgraphicssceneqgraphicsitem
13 Posts 3 Posters 1.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    StudentScripter
    wrote on last edited by StudentScripter
    #1

    So i have a qgraphicsscene and in the mouserelease event im adding all selected qgraphicsitems to another qgraphicsrectitem called "GroupSelectionRect". Im making the children itself unmovable and unselecteable but the parent item stays movable. I move the parent item and click somewhere else. In the mousepress event when clicked somwhere else i remove the parent from the children.
    EVERYTHING works fine till here. But than i select the items again and they get added to the "GroupSelectionRect" they have been removed from. At this point the childitems aswell as the "GroupSelectionRect" jumps to an random position in the qgraphicsscene and i couldn't figure out WHY and how to fix that?

    Here is my code:
    mousepress (removing from group if not clicked on groupitem:

    
    void CustomGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
    
        if(GroupSelectionRect && (GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos()))))
        {
            // Der Mausklick erfolgte innerhalb des Bereichs von GroupSelectionRect
            // Führen Sie Ihre Aktionen hier aus
            qDebug() << "AUF das GruppenRect geklcikt";
            clickedOnGroupRect = true;
    
    
        }else if(GroupSelectionRect && !GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos())))
        {
    
    
            clickedOnGroupRect = false;
    
            if(GroupSelectionRect && !GroupSelectionRect->childItems().isEmpty()){
    
    
                foreach (QGraphicsItem *item, GroupSelectionRect->childItems()) {
    
    
                    QPointF globalPos = item->mapToScene(0, 0);
    
                   item->setPos(globalPos);
                    item->setParentItem(nullptr);
                    item->setSelected(false);
    
    
    
                    // Check if the item is a pixmap item or a rect item
                    ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                    if(rectItem){
                        rectItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
                    }
    
    
                }
    
    
            }
    
    
    
        }
    
    
    
        QGraphicsScene::mousePressEvent(event);
    }
    

    mouse release: (adding to group)

    void CustomGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    {
    
        if(DragSelectionInProgress == true){
    
                qDebug() << "SelectionInProgress" << GroupSelectionRect;
    
            //Erstelle eine Liste aller selecteten items die nicht das grouprect sind und füge alle items dieser Liste dem grouprect hinzu
            if(GroupSelectionRect){
                QList<QGraphicsItem *> selectedItems = this->selectedItems();
                QList<QGraphicsItem *> itemsToAdd;
                qDebug() << "SELItems:" << selectedItems;
    
                foreach(QGraphicsItem *item, selectedItems) {
                    if(item != GroupSelectionRect && item) {
                         ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                        if(rectItem){
                            // Wenn das Element kein resizablehandlerect ist, füge es der Liste hinzu
                            itemsToAdd.append(item);
                            qDebug() << "ItemToAppend:" << itemsToAdd.count();
                        }
    
                    }
                }
    
    
                QRectF CombinedBoundingRect;
    
                if(itemsToAdd.count() > 1){
                foreach(QGraphicsItem *item, itemsToAdd) {
                        // Check if the item is a pixmap item or a rect item
                        ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                        if(rectItem){
    
                            rectItem->setFlags(rectItem->flags() & ~(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable));
                            rectItem->setSelected(false);
    
                            rectItem->setParentItem(GroupSelectionRect);
                            qDebug() << "Parent:" << rectItem->parentItem();
    
                            CombinedBoundingRect = CombinedBoundingRect.united(rectItem->sceneBoundingRect());
                        }
    
                }
                GroupSelectionRect->setRect(CombinedBoundingRect);
                
                }
    
            }
    
    
    
    
    
        DragSelectionInProgress = false;
        }else{
    
    
    
        }
    
        QGraphicsScene::mouseReleaseEvent(event);
    
    
    }
    
    jsulmJ A 3 Replies Last reply
    0
    • S StudentScripter

      So i have a qgraphicsscene and in the mouserelease event im adding all selected qgraphicsitems to another qgraphicsrectitem called "GroupSelectionRect". Im making the children itself unmovable and unselecteable but the parent item stays movable. I move the parent item and click somewhere else. In the mousepress event when clicked somwhere else i remove the parent from the children.
      EVERYTHING works fine till here. But than i select the items again and they get added to the "GroupSelectionRect" they have been removed from. At this point the childitems aswell as the "GroupSelectionRect" jumps to an random position in the qgraphicsscene and i couldn't figure out WHY and how to fix that?

      Here is my code:
      mousepress (removing from group if not clicked on groupitem:

      
      void CustomGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
      {
      
          if(GroupSelectionRect && (GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos()))))
          {
              // Der Mausklick erfolgte innerhalb des Bereichs von GroupSelectionRect
              // Führen Sie Ihre Aktionen hier aus
              qDebug() << "AUF das GruppenRect geklcikt";
              clickedOnGroupRect = true;
      
      
          }else if(GroupSelectionRect && !GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos())))
          {
      
      
              clickedOnGroupRect = false;
      
              if(GroupSelectionRect && !GroupSelectionRect->childItems().isEmpty()){
      
      
                  foreach (QGraphicsItem *item, GroupSelectionRect->childItems()) {
      
      
                      QPointF globalPos = item->mapToScene(0, 0);
      
                     item->setPos(globalPos);
                      item->setParentItem(nullptr);
                      item->setSelected(false);
      
      
      
                      // Check if the item is a pixmap item or a rect item
                      ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                      if(rectItem){
                          rectItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
                      }
      
      
                  }
      
      
              }
      
      
      
          }
      
      
      
          QGraphicsScene::mousePressEvent(event);
      }
      

      mouse release: (adding to group)

      void CustomGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
      {
      
          if(DragSelectionInProgress == true){
      
                  qDebug() << "SelectionInProgress" << GroupSelectionRect;
      
              //Erstelle eine Liste aller selecteten items die nicht das grouprect sind und füge alle items dieser Liste dem grouprect hinzu
              if(GroupSelectionRect){
                  QList<QGraphicsItem *> selectedItems = this->selectedItems();
                  QList<QGraphicsItem *> itemsToAdd;
                  qDebug() << "SELItems:" << selectedItems;
      
                  foreach(QGraphicsItem *item, selectedItems) {
                      if(item != GroupSelectionRect && item) {
                           ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                          if(rectItem){
                              // Wenn das Element kein resizablehandlerect ist, füge es der Liste hinzu
                              itemsToAdd.append(item);
                              qDebug() << "ItemToAppend:" << itemsToAdd.count();
                          }
      
                      }
                  }
      
      
                  QRectF CombinedBoundingRect;
      
                  if(itemsToAdd.count() > 1){
                  foreach(QGraphicsItem *item, itemsToAdd) {
                          // Check if the item is a pixmap item or a rect item
                          ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                          if(rectItem){
      
                              rectItem->setFlags(rectItem->flags() & ~(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable));
                              rectItem->setSelected(false);
      
                              rectItem->setParentItem(GroupSelectionRect);
                              qDebug() << "Parent:" << rectItem->parentItem();
      
                              CombinedBoundingRect = CombinedBoundingRect.united(rectItem->sceneBoundingRect());
                          }
      
                  }
                  GroupSelectionRect->setRect(CombinedBoundingRect);
                  
                  }
      
              }
      
      
      
      
      
          DragSelectionInProgress = false;
          }else{
      
      
      
          }
      
          QGraphicsScene::mouseReleaseEvent(event);
      
      
      }
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @StudentScripter said in Qgraphicsscene setParentItem update childrens position?:

      item->setPos(globalPos);
      item->setParentItem(nullptr);

      I don't understand your code - why do you unset the parent?
      Also, if you unset the parent you should set the position afterwards, not before.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      S 1 Reply Last reply
      0
      • jsulmJ jsulm

        @StudentScripter said in Qgraphicsscene setParentItem update childrens position?:

        item->setPos(globalPos);
        item->setParentItem(nullptr);

        I don't understand your code - why do you unset the parent?
        Also, if you unset the parent you should set the position afterwards, not before.

        S Offline
        S Offline
        StudentScripter
        wrote on last edited by
        #3

        @jsulm Cause its like an temporary group. As long as more than 2 items are selected this groupitem is created to move all the items at once. Than when clicked somwhere else not on the group the parent is unset in order to make the items move independently again.

        1 Reply Last reply
        0
        • S StudentScripter

          So i have a qgraphicsscene and in the mouserelease event im adding all selected qgraphicsitems to another qgraphicsrectitem called "GroupSelectionRect". Im making the children itself unmovable and unselecteable but the parent item stays movable. I move the parent item and click somewhere else. In the mousepress event when clicked somwhere else i remove the parent from the children.
          EVERYTHING works fine till here. But than i select the items again and they get added to the "GroupSelectionRect" they have been removed from. At this point the childitems aswell as the "GroupSelectionRect" jumps to an random position in the qgraphicsscene and i couldn't figure out WHY and how to fix that?

          Here is my code:
          mousepress (removing from group if not clicked on groupitem:

          
          void CustomGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
          {
          
              if(GroupSelectionRect && (GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos()))))
              {
                  // Der Mausklick erfolgte innerhalb des Bereichs von GroupSelectionRect
                  // Führen Sie Ihre Aktionen hier aus
                  qDebug() << "AUF das GruppenRect geklcikt";
                  clickedOnGroupRect = true;
          
          
              }else if(GroupSelectionRect && !GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos())))
              {
          
          
                  clickedOnGroupRect = false;
          
                  if(GroupSelectionRect && !GroupSelectionRect->childItems().isEmpty()){
          
          
                      foreach (QGraphicsItem *item, GroupSelectionRect->childItems()) {
          
          
                          QPointF globalPos = item->mapToScene(0, 0);
          
                         item->setPos(globalPos);
                          item->setParentItem(nullptr);
                          item->setSelected(false);
          
          
          
                          // Check if the item is a pixmap item or a rect item
                          ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                          if(rectItem){
                              rectItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
                          }
          
          
                      }
          
          
                  }
          
          
          
              }
          
          
          
              QGraphicsScene::mousePressEvent(event);
          }
          

          mouse release: (adding to group)

          void CustomGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
          {
          
              if(DragSelectionInProgress == true){
          
                      qDebug() << "SelectionInProgress" << GroupSelectionRect;
          
                  //Erstelle eine Liste aller selecteten items die nicht das grouprect sind und füge alle items dieser Liste dem grouprect hinzu
                  if(GroupSelectionRect){
                      QList<QGraphicsItem *> selectedItems = this->selectedItems();
                      QList<QGraphicsItem *> itemsToAdd;
                      qDebug() << "SELItems:" << selectedItems;
          
                      foreach(QGraphicsItem *item, selectedItems) {
                          if(item != GroupSelectionRect && item) {
                               ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                              if(rectItem){
                                  // Wenn das Element kein resizablehandlerect ist, füge es der Liste hinzu
                                  itemsToAdd.append(item);
                                  qDebug() << "ItemToAppend:" << itemsToAdd.count();
                              }
          
                          }
                      }
          
          
                      QRectF CombinedBoundingRect;
          
                      if(itemsToAdd.count() > 1){
                      foreach(QGraphicsItem *item, itemsToAdd) {
                              // Check if the item is a pixmap item or a rect item
                              ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                              if(rectItem){
          
                                  rectItem->setFlags(rectItem->flags() & ~(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable));
                                  rectItem->setSelected(false);
          
                                  rectItem->setParentItem(GroupSelectionRect);
                                  qDebug() << "Parent:" << rectItem->parentItem();
          
                                  CombinedBoundingRect = CombinedBoundingRect.united(rectItem->sceneBoundingRect());
                              }
          
                      }
                      GroupSelectionRect->setRect(CombinedBoundingRect);
                      
                      }
          
                  }
          
          
          
          
          
              DragSelectionInProgress = false;
              }else{
          
          
          
              }
          
              QGraphicsScene::mouseReleaseEvent(event);
          
          
          }
          
          A Offline
          A Offline
          Asperamanca
          wrote on last edited by
          #4

          @StudentScripter said in Qgraphicsscene setParentItem update childrens position?:

                      QPointF globalPos = item->mapToScene(0, 0);
          
                     item->setPos(globalPos);
          

          This is wrong.
          You get a global position, and then set it as an item position. Then you change the parent (and thereby the coordinate system).

          What you probably want to do is something like:

          auto scenePos = item->scenePos();
          item->setParentItem(nullptr);
          item->setScenePos(scenePos);
          

          I really recommend reading
          https://doc.qt.io/qt-6/graphicsview.html#the-graphics-view-coordinate-system

          S 1 Reply Last reply
          2
          • A Asperamanca

            @StudentScripter said in Qgraphicsscene setParentItem update childrens position?:

                        QPointF globalPos = item->mapToScene(0, 0);
            
                       item->setPos(globalPos);
            

            This is wrong.
            You get a global position, and then set it as an item position. Then you change the parent (and thereby the coordinate system).

            What you probably want to do is something like:

            auto scenePos = item->scenePos();
            item->setParentItem(nullptr);
            item->setScenePos(scenePos);
            

            I really recommend reading
            https://doc.qt.io/qt-6/graphicsview.html#the-graphics-view-coordinate-system

            S Offline
            S Offline
            StudentScripter
            wrote on last edited by
            #5

            @Asperamanca said in Qgraphicsscene setParentItem update childrens position?:

            item->setScenePos(scenePos);

            Thanks but there is no "setScenePos" with QGraphicsItem.

            A 1 Reply Last reply
            0
            • S StudentScripter

              @Asperamanca said in Qgraphicsscene setParentItem update childrens position?:

              item->setScenePos(scenePos);

              Thanks but there is no "setScenePos" with QGraphicsItem.

              A Offline
              A Offline
              Asperamanca
              wrote on last edited by Asperamanca
              #6

              @StudentScripter
              Ah yes, don't get me started on the API design of that thing...

              That should do instead

              pItem->setPos(scenePos);
              

              Given that you just the the parent to nullptr, it's a top-level item, and thereby pos and scenePos are equivalent.

              S 1 Reply Last reply
              3
              • A Asperamanca

                @StudentScripter
                Ah yes, don't get me started on the API design of that thing...

                That should do instead

                pItem->setPos(scenePos);
                

                Given that you just the the parent to nullptr, it's a top-level item, and thereby pos and scenePos are equivalent.

                S Offline
                S Offline
                StudentScripter
                wrote on last edited by StudentScripter
                #7

                @Asperamanca Thanks i tried it but sadly it doesn't fix the issue. Here is a gif of the issue. Hope this helps, i really can't find the way to make it work properly.

                Wanted to share a gif of the issues but even with a 6mb small one it says file to big to upload. Here some pictures instead:

                Just two items added to scene:
                fa6e73c2-7f15-4866-ba78-76376b267b25-image.png
                I select both they keep their position all good and the grouprect is drawn:
                cfa3dfd7-b09d-40b7-8765-b7f81d3816c2-image.png I select the grouprect and move it, works fine: 08fafebf-7d1f-4b64-8c1a-242f634eb619-image.png
                I click somwhere else so the items are unparented works fine too i move the group rect away: 17e388c5-e1b2-48cd-a899-26baa25198fe-image.png NOW i try selecting the two items again, but now everything is moved totaly random: 1bc4cf8e-6438-4cdf-af5f-d8d2e935fe18-image.png

                1 Reply Last reply
                0
                • S StudentScripter

                  So i have a qgraphicsscene and in the mouserelease event im adding all selected qgraphicsitems to another qgraphicsrectitem called "GroupSelectionRect". Im making the children itself unmovable and unselecteable but the parent item stays movable. I move the parent item and click somewhere else. In the mousepress event when clicked somwhere else i remove the parent from the children.
                  EVERYTHING works fine till here. But than i select the items again and they get added to the "GroupSelectionRect" they have been removed from. At this point the childitems aswell as the "GroupSelectionRect" jumps to an random position in the qgraphicsscene and i couldn't figure out WHY and how to fix that?

                  Here is my code:
                  mousepress (removing from group if not clicked on groupitem:

                  
                  void CustomGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
                  {
                  
                      if(GroupSelectionRect && (GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos()))))
                      {
                          // Der Mausklick erfolgte innerhalb des Bereichs von GroupSelectionRect
                          // Führen Sie Ihre Aktionen hier aus
                          qDebug() << "AUF das GruppenRect geklcikt";
                          clickedOnGroupRect = true;
                  
                  
                      }else if(GroupSelectionRect && !GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos())))
                      {
                  
                  
                          clickedOnGroupRect = false;
                  
                          if(GroupSelectionRect && !GroupSelectionRect->childItems().isEmpty()){
                  
                  
                              foreach (QGraphicsItem *item, GroupSelectionRect->childItems()) {
                  
                  
                                  QPointF globalPos = item->mapToScene(0, 0);
                  
                                 item->setPos(globalPos);
                                  item->setParentItem(nullptr);
                                  item->setSelected(false);
                  
                  
                  
                                  // Check if the item is a pixmap item or a rect item
                                  ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                                  if(rectItem){
                                      rectItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
                                  }
                  
                  
                              }
                  
                  
                          }
                  
                  
                  
                      }
                  
                  
                  
                      QGraphicsScene::mousePressEvent(event);
                  }
                  

                  mouse release: (adding to group)

                  void CustomGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
                  {
                  
                      if(DragSelectionInProgress == true){
                  
                              qDebug() << "SelectionInProgress" << GroupSelectionRect;
                  
                          //Erstelle eine Liste aller selecteten items die nicht das grouprect sind und füge alle items dieser Liste dem grouprect hinzu
                          if(GroupSelectionRect){
                              QList<QGraphicsItem *> selectedItems = this->selectedItems();
                              QList<QGraphicsItem *> itemsToAdd;
                              qDebug() << "SELItems:" << selectedItems;
                  
                              foreach(QGraphicsItem *item, selectedItems) {
                                  if(item != GroupSelectionRect && item) {
                                       ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                                      if(rectItem){
                                          // Wenn das Element kein resizablehandlerect ist, füge es der Liste hinzu
                                          itemsToAdd.append(item);
                                          qDebug() << "ItemToAppend:" << itemsToAdd.count();
                                      }
                  
                                  }
                              }
                  
                  
                              QRectF CombinedBoundingRect;
                  
                              if(itemsToAdd.count() > 1){
                              foreach(QGraphicsItem *item, itemsToAdd) {
                                      // Check if the item is a pixmap item or a rect item
                                      ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                                      if(rectItem){
                  
                                          rectItem->setFlags(rectItem->flags() & ~(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable));
                                          rectItem->setSelected(false);
                  
                                          rectItem->setParentItem(GroupSelectionRect);
                                          qDebug() << "Parent:" << rectItem->parentItem();
                  
                                          CombinedBoundingRect = CombinedBoundingRect.united(rectItem->sceneBoundingRect());
                                      }
                  
                              }
                              GroupSelectionRect->setRect(CombinedBoundingRect);
                              
                              }
                  
                          }
                  
                  
                  
                  
                  
                      DragSelectionInProgress = false;
                      }else{
                  
                  
                  
                      }
                  
                      QGraphicsScene::mouseReleaseEvent(event);
                  
                  
                  }
                  
                  A Offline
                  A Offline
                  Asperamanca
                  wrote on last edited by
                  #8

                  @StudentScripter said in Qgraphicsscene setParentItem update childrens position?:

                                  if(rectItem){
                  
                                      rectItem->setFlags(rectItem->flags() & ~(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable));
                                      rectItem->setSelected(false);
                  
                                      rectItem->setParentItem(GroupSelectionRect);
                                      qDebug() << "Parent:" << rectItem->parentItem();
                  
                                      CombinedBoundingRect = CombinedBoundingRect.united(rectItem->sceneBoundingRect());
                                  }
                  

                  Well, same story. After setParentItem in the above code, you have to correct the itemPos, since the coordinate system has changed.
                  You can use the same approach getting scenePos before, but now you need to map the scenePos to the correct coordinate system using

                  auto newItemPos = GroupSelectionRect->mapFromScene(scenePos);
                  
                  S 1 Reply Last reply
                  1
                  • A Asperamanca

                    @StudentScripter said in Qgraphicsscene setParentItem update childrens position?:

                                    if(rectItem){
                    
                                        rectItem->setFlags(rectItem->flags() & ~(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable));
                                        rectItem->setSelected(false);
                    
                                        rectItem->setParentItem(GroupSelectionRect);
                                        qDebug() << "Parent:" << rectItem->parentItem();
                    
                                        CombinedBoundingRect = CombinedBoundingRect.united(rectItem->sceneBoundingRect());
                                    }
                    

                    Well, same story. After setParentItem in the above code, you have to correct the itemPos, since the coordinate system has changed.
                    You can use the same approach getting scenePos before, but now you need to map the scenePos to the correct coordinate system using

                    auto newItemPos = GroupSelectionRect->mapFromScene(scenePos);
                    
                    S Offline
                    S Offline
                    StudentScripter
                    wrote on last edited by StudentScripter
                    #9

                    @Asperamanca said in Qgraphicsscene setParentItem update childrens position?:

                    auto newItemPos = GroupSelectionRect->mapFromScene(scenePos);

                    Really thanks for trying to help me that much, but i don't quite get how to do it.

                    This is obviously wrong:

                    
                    
                    
                                QRectF CombinedBoundingRect;
                    
                    
                                if(itemsToAdd.count() > 1){
                                foreach(QGraphicsItem *item, itemsToAdd) {
                                        // Check if the item is a pixmap item or a rect item
                                        ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                                        if(rectItem){
                    
                                            // Speichere die aktuelle Szene-Position
                                            QPointF scenePos = rectItem->scenePos();
                    
                    
                                            rectItem->setFlags(rectItem->flags() & ~(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable));
                                            rectItem->setSelected(false);
                    
                    
                                            rectItem->setParentItem(GroupSelectionRect);
                    
                    
                                            qDebug() << "Parent:" << rectItem->parentItem();
                    
                    
                    
                                            rectItem->setPos(scenePos);
                                            CombinedBoundingRect = CombinedBoundingRect.united(rectItem->sceneBoundingRect());
                    
                                        }
                    
                                }
                                GroupSelectionRect->setRect(CombinedBoundingRect);
                    
                    
                    
                    
                    
                                }
                    
                    A 1 Reply Last reply
                    0
                    • S StudentScripter

                      @Asperamanca said in Qgraphicsscene setParentItem update childrens position?:

                      auto newItemPos = GroupSelectionRect->mapFromScene(scenePos);

                      Really thanks for trying to help me that much, but i don't quite get how to do it.

                      This is obviously wrong:

                      
                      
                      
                                  QRectF CombinedBoundingRect;
                      
                      
                                  if(itemsToAdd.count() > 1){
                                  foreach(QGraphicsItem *item, itemsToAdd) {
                                          // Check if the item is a pixmap item or a rect item
                                          ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                                          if(rectItem){
                      
                                              // Speichere die aktuelle Szene-Position
                                              QPointF scenePos = rectItem->scenePos();
                      
                      
                                              rectItem->setFlags(rectItem->flags() & ~(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable));
                                              rectItem->setSelected(false);
                      
                      
                                              rectItem->setParentItem(GroupSelectionRect);
                      
                      
                                              qDebug() << "Parent:" << rectItem->parentItem();
                      
                      
                      
                                              rectItem->setPos(scenePos);
                                              CombinedBoundingRect = CombinedBoundingRect.united(rectItem->sceneBoundingRect());
                      
                                          }
                      
                                  }
                                  GroupSelectionRect->setRect(CombinedBoundingRect);
                      
                      
                      
                      
                      
                                  }
                      
                      A Offline
                      A Offline
                      Asperamanca
                      wrote on last edited by
                      #10

                      @StudentScripter said in Qgraphicsscene setParentItem update childrens position?:

                                          rectItem->setParentItem(GroupSelectionRect);
                      
                      
                                          qDebug() << "Parent:" << rectItem->parentItem();
                      
                      
                      
                                          rectItem->setPos(scenePos);
                      

                      Should be

                      rectItem->setParentItem(GroupSelectionRect);
                      qDebug() << "Parent:" << rectItem->parentItem();
                      auto newItemPos = GroupSelectionRect->mapFromScene(scenePos);
                      rectItem->setPos(newItemPos);
                      

                      Maybe I shouldn't answer questions when I am in a hurry. But I really recommend reading that chapter I posted. If you understand the coordinate system, it's all logical (if not always easy).

                      S 1 Reply Last reply
                      2
                      • A Asperamanca

                        @StudentScripter said in Qgraphicsscene setParentItem update childrens position?:

                                            rectItem->setParentItem(GroupSelectionRect);
                        
                        
                                            qDebug() << "Parent:" << rectItem->parentItem();
                        
                        
                        
                                            rectItem->setPos(scenePos);
                        

                        Should be

                        rectItem->setParentItem(GroupSelectionRect);
                        qDebug() << "Parent:" << rectItem->parentItem();
                        auto newItemPos = GroupSelectionRect->mapFromScene(scenePos);
                        rectItem->setPos(newItemPos);
                        

                        Maybe I shouldn't answer questions when I am in a hurry. But I really recommend reading that chapter I posted. If you understand the coordinate system, it's all logical (if not always easy).

                        S Offline
                        S Offline
                        StudentScripter
                        wrote on last edited by StudentScripter
                        #11

                        @Asperamanca Thank you very much, can't express how much this helps <3, so now my children items don't move randomly anymore. (English is not my mothertongue so understanding everything right is indeed not that easy for me.) Gonna have a look again on the manual page you posted. Cause i have one problem that still persists. Even tho the children items don't move wrongly the parent item is offset everytime a little depending on how much it was moved before.

                        EDIT: Actually SOLVED it by doing:

                         GroupSelectionRect->setRect(CombinedBoundingRect.x()-GroupSelectionRect->scenePos().x(),CombinedBoundingRect.y()-GroupSelectionRect->scenePos().y(), CombinedBoundingRect.width(), CombinedBoundingRect.height());
                        

                        But i wanted to know if thats a good way to do it or if there is an better way?

                        .
                        .
                        .
                        .

                        Here some pictures to show what happens:

                        1. Just added 2 items nothing special again:
                          4c94a05a-32bc-4c35-a2d7-b75ae031cb0f-image.png
                        2. i select both items, grouprect is created, everything works fine:
                          aa4db775-5855-4e6f-914e-b09c61f8a502-image.png
                        3. Moved the grouprect all fine: 843f9056-0dd6-4b11-87c1-54b26995e01b-image.png 4) NOW when i unselect an select again the children stay which is good but the parent item on reselecting is offsetted: 348b275f-1ea2-4b01-9b03-be213ee4e467-image.png

                        Code for adding to group in mouserelease:

                            if(DragSelectionInProgress == true){
                        
                                    qDebug() << "SelectionInProgress" << GroupSelectionRect;
                        
                                //Erstelle eine Liste aller selecteten items die nicht das grouprect sind und füge alle items dieser Liste dem grouprect hinzu
                                if(GroupSelectionRect){
                                    QList<QGraphicsItem *> selectedItems = this->selectedItems();
                                    QList<QGraphicsItem *> itemsToAdd;
                                    qDebug() << "SELItems:" << selectedItems;
                        
                                    foreach(QGraphicsItem *item, selectedItems) {
                                        if(item != GroupSelectionRect && item) {
                                             ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                                            if(rectItem){
                                                // Wenn das Element kein resizablehandlerect ist, füge es der Liste hinzu
                                                itemsToAdd.append(item);
                                                qDebug() << "ItemToAppend:" << itemsToAdd.count();
                                            }
                        
                                        }
                                    }
                        
                        
                        
                                    QRectF CombinedBoundingRect;
                        
                        
                                    if(itemsToAdd.count() > 1){
                                    foreach(QGraphicsItem *item, itemsToAdd) {
                                            // Check if the item is a pixmap item or a rect item
                                            ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                                            if(rectItem){
                                                // Speichere die aktuelle Szene-Position
                                                QPointF scenePos = rectItem->scenePos();
                        
                                                rectItem->setFlags(rectItem->flags() & ~(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable));
                                                rectItem->setSelected(false);
                        
                        
                                                rectItem->setParentItem(GroupSelectionRect);
                                                auto newItemPos = GroupSelectionRect->mapFromScene(scenePos);
                                                rectItem->setPos(newItemPos);
                        
                        
                                                qDebug() << rectItem->scenePos() << "NWItemPos:" << newItemPos;
                        
                        
                                                CombinedBoundingRect = CombinedBoundingRect.united(rectItem->sceneBoundingRect());
                        
                                            }
                        
                                    }
                        
                        
                                    GroupSelectionRect->setRect(CombinedBoundingRect);
                        
                                    GroupSelectionRect->drawHandlesIfNecessary(true);
                                    GroupSelectionRect->setSelected(true);
                        
                        
                                    qDebug() << GroupSelectionRect->pos() << GroupSelectionRect->scenePos();
                        
                        
                        
                        
                        
                        
                        
                                    }
                        
                                }
                        
                        
                        
                        
                        
                            DragSelectionInProgress = false;
                            }else{
                        
                        
                        
                            }
                        
                            QGraphicsScene::mouseReleaseEvent(event);
                        
                        
                        }
                        

                        Code for removing from group on mousepress:

                            if(GroupSelectionRect && (GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos()))))
                            {
                                // Der Mausklick erfolgte innerhalb des Bereichs von GroupSelectionRect
                                // Führen Sie Ihre Aktionen hier aus
                                qDebug() << "AUF das GruppenRect geklcikt";
                                clickedOnGroupRect = true;
                        
                        
                            }else if(GroupSelectionRect && !GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos())))
                            {
                        
                        
                                clickedOnGroupRect = false;
                        
                                if(GroupSelectionRect && !GroupSelectionRect->childItems().isEmpty()){
                        
                        
                                    foreach (QGraphicsItem *item, GroupSelectionRect->childItems()) {
                        
                        
                                        //QPointF globalPos = item->mapToScene(0, 0);
                        
                                      // item->setPos(globalPos);
                                        auto scenePos = item->scenePos();
                        
                                        item->setParentItem(nullptr);
                                        //item->setSelected(false);
                        
                                        item->setPos(scenePos);
                        
                        
                                        // Check if the item is a pixmap item or a rect item
                                        ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                                        if(rectItem){
                                            rectItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
                        
                                        }
                        
                        
                                    }
                                    GroupSelectionRect->drawHandlesIfNecessary(false);
                                    qDebug()<< "PArentRect:" << GroupSelectionRect->scenePos();
                        
                                    GroupSelectionRect->setRect(0,0,0,0);
                        
                                }
                        
                        
                        
                            }
                        
                        
                        
                            QGraphicsScene::mousePressEvent(event);
                        
                        A 1 Reply Last reply
                        0
                        • S StudentScripter

                          @Asperamanca Thank you very much, can't express how much this helps <3, so now my children items don't move randomly anymore. (English is not my mothertongue so understanding everything right is indeed not that easy for me.) Gonna have a look again on the manual page you posted. Cause i have one problem that still persists. Even tho the children items don't move wrongly the parent item is offset everytime a little depending on how much it was moved before.

                          EDIT: Actually SOLVED it by doing:

                           GroupSelectionRect->setRect(CombinedBoundingRect.x()-GroupSelectionRect->scenePos().x(),CombinedBoundingRect.y()-GroupSelectionRect->scenePos().y(), CombinedBoundingRect.width(), CombinedBoundingRect.height());
                          

                          But i wanted to know if thats a good way to do it or if there is an better way?

                          .
                          .
                          .
                          .

                          Here some pictures to show what happens:

                          1. Just added 2 items nothing special again:
                            4c94a05a-32bc-4c35-a2d7-b75ae031cb0f-image.png
                          2. i select both items, grouprect is created, everything works fine:
                            aa4db775-5855-4e6f-914e-b09c61f8a502-image.png
                          3. Moved the grouprect all fine: 843f9056-0dd6-4b11-87c1-54b26995e01b-image.png 4) NOW when i unselect an select again the children stay which is good but the parent item on reselecting is offsetted: 348b275f-1ea2-4b01-9b03-be213ee4e467-image.png

                          Code for adding to group in mouserelease:

                              if(DragSelectionInProgress == true){
                          
                                      qDebug() << "SelectionInProgress" << GroupSelectionRect;
                          
                                  //Erstelle eine Liste aller selecteten items die nicht das grouprect sind und füge alle items dieser Liste dem grouprect hinzu
                                  if(GroupSelectionRect){
                                      QList<QGraphicsItem *> selectedItems = this->selectedItems();
                                      QList<QGraphicsItem *> itemsToAdd;
                                      qDebug() << "SELItems:" << selectedItems;
                          
                                      foreach(QGraphicsItem *item, selectedItems) {
                                          if(item != GroupSelectionRect && item) {
                                               ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                                              if(rectItem){
                                                  // Wenn das Element kein resizablehandlerect ist, füge es der Liste hinzu
                                                  itemsToAdd.append(item);
                                                  qDebug() << "ItemToAppend:" << itemsToAdd.count();
                                              }
                          
                                          }
                                      }
                          
                          
                          
                                      QRectF CombinedBoundingRect;
                          
                          
                                      if(itemsToAdd.count() > 1){
                                      foreach(QGraphicsItem *item, itemsToAdd) {
                                              // Check if the item is a pixmap item or a rect item
                                              ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                                              if(rectItem){
                                                  // Speichere die aktuelle Szene-Position
                                                  QPointF scenePos = rectItem->scenePos();
                          
                                                  rectItem->setFlags(rectItem->flags() & ~(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable));
                                                  rectItem->setSelected(false);
                          
                          
                                                  rectItem->setParentItem(GroupSelectionRect);
                                                  auto newItemPos = GroupSelectionRect->mapFromScene(scenePos);
                                                  rectItem->setPos(newItemPos);
                          
                          
                                                  qDebug() << rectItem->scenePos() << "NWItemPos:" << newItemPos;
                          
                          
                                                  CombinedBoundingRect = CombinedBoundingRect.united(rectItem->sceneBoundingRect());
                          
                                              }
                          
                                      }
                          
                          
                                      GroupSelectionRect->setRect(CombinedBoundingRect);
                          
                                      GroupSelectionRect->drawHandlesIfNecessary(true);
                                      GroupSelectionRect->setSelected(true);
                          
                          
                                      qDebug() << GroupSelectionRect->pos() << GroupSelectionRect->scenePos();
                          
                          
                          
                          
                          
                          
                          
                                      }
                          
                                  }
                          
                          
                          
                          
                          
                              DragSelectionInProgress = false;
                              }else{
                          
                          
                          
                              }
                          
                              QGraphicsScene::mouseReleaseEvent(event);
                          
                          
                          }
                          

                          Code for removing from group on mousepress:

                              if(GroupSelectionRect && (GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos()))))
                              {
                                  // Der Mausklick erfolgte innerhalb des Bereichs von GroupSelectionRect
                                  // Führen Sie Ihre Aktionen hier aus
                                  qDebug() << "AUF das GruppenRect geklcikt";
                                  clickedOnGroupRect = true;
                          
                          
                              }else if(GroupSelectionRect && !GroupSelectionRect->boundingRect().adjusted(-8, -8, 8, 8).contains(GroupSelectionRect->mapFromScene(event->scenePos())))
                              {
                          
                          
                                  clickedOnGroupRect = false;
                          
                                  if(GroupSelectionRect && !GroupSelectionRect->childItems().isEmpty()){
                          
                          
                                      foreach (QGraphicsItem *item, GroupSelectionRect->childItems()) {
                          
                          
                                          //QPointF globalPos = item->mapToScene(0, 0);
                          
                                        // item->setPos(globalPos);
                                          auto scenePos = item->scenePos();
                          
                                          item->setParentItem(nullptr);
                                          //item->setSelected(false);
                          
                                          item->setPos(scenePos);
                          
                          
                                          // Check if the item is a pixmap item or a rect item
                                          ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);
                                          if(rectItem){
                                              rectItem->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
                          
                                          }
                          
                          
                                      }
                                      GroupSelectionRect->drawHandlesIfNecessary(false);
                                      qDebug()<< "PArentRect:" << GroupSelectionRect->scenePos();
                          
                                      GroupSelectionRect->setRect(0,0,0,0);
                          
                                  }
                          
                          
                          
                              }
                          
                          
                          
                              QGraphicsScene::mousePressEvent(event);
                          
                          A Offline
                          A Offline
                          Asperamanca
                          wrote on last edited by Asperamanca
                          #12

                          @StudentScripter Hard for me to say whether this is a good way for you to do things. Much of that depends on what else you want to do in your application. Maybe this way to implement it is in the way of another feature in the future, maybe you can reuse part of it for something else. I don't know enough to have an opinion on that.

                          I can however highlight some detail points:

                          • Replace 'foreach' with C++ ranged for loop
                          foreach(QGraphicsItem *item, selectedItems)
                          

                          becomes

                          for(QGraphicsItem* item : selectedItems)
                          

                          Even better, make it

                          for(QGraphicsItem* const item : selectedItems)
                          

                          (unless you plan to change the pointer, but that's not a great idea in most cases)
                          Even shorter, you can also write

                          for(auto* const item : selectedItems)
                          

                          The compiler knows what type you need.

                          • Package your code in some named functions or lambdas

                          With good names, this makes the code way easier to read. It also shows explicitly what goes into the function, and might give you hints on where your code could be better designed and ordered.

                          • Take a look at QGraphicsItem::ItemChange

                          This function allows you to respond to various changes to the item. You could, for example, do the coordinate transformation (when the item's parent changes) in the item itself, instead of in the event. Whether that's a good idea, I'm not sure. But it's good to know it's possible.

                          • ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);

                          I see that in a couple of places, you downcast to your item type. But the following code only uses functionality of QGraphicsItem. Any special reason you do that? The list you loop through shouldn't have any "wrong" items anyway, as far as I see...

                          S 1 Reply Last reply
                          0
                          • A Asperamanca

                            @StudentScripter Hard for me to say whether this is a good way for you to do things. Much of that depends on what else you want to do in your application. Maybe this way to implement it is in the way of another feature in the future, maybe you can reuse part of it for something else. I don't know enough to have an opinion on that.

                            I can however highlight some detail points:

                            • Replace 'foreach' with C++ ranged for loop
                            foreach(QGraphicsItem *item, selectedItems)
                            

                            becomes

                            for(QGraphicsItem* item : selectedItems)
                            

                            Even better, make it

                            for(QGraphicsItem* const item : selectedItems)
                            

                            (unless you plan to change the pointer, but that's not a great idea in most cases)
                            Even shorter, you can also write

                            for(auto* const item : selectedItems)
                            

                            The compiler knows what type you need.

                            • Package your code in some named functions or lambdas

                            With good names, this makes the code way easier to read. It also shows explicitly what goes into the function, and might give you hints on where your code could be better designed and ordered.

                            • Take a look at QGraphicsItem::ItemChange

                            This function allows you to respond to various changes to the item. You could, for example, do the coordinate transformation (when the item's parent changes) in the item itself, instead of in the event. Whether that's a good idea, I'm not sure. But it's good to know it's possible.

                            • ResizablePixmapItem *rectItem = qgraphicsitem_cast<ResizablePixmapItem *>(item);

                            I see that in a couple of places, you downcast to your item type. But the following code only uses functionality of QGraphicsItem. Any special reason you do that? The list you loop through shouldn't have any "wrong" items anyway, as far as I see...

                            S Offline
                            S Offline
                            StudentScripter
                            wrote on last edited by
                            #13

                            @Asperamanca Thanks thats a good call, gonna have a look at it. Thanks for the time and effort. <3 Gonna write again here if i encounter other questions regarding this. :D

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved