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?
Forum Updated to NodeBB v4.3 + New Features

Qgraphicsscene setParentItem update childrens position?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qt c++parent & childqgraphicssceneqgraphicsitem
13 Posts 3 Posters 1.7k Views 2 Watching
  • 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.
  • 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