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?

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 StudentScripter
    9 Feb 2024, 10:00

    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 9 Feb 2024, 10:19 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 9 Feb 2024, 10:24
    2
    • A Asperamanca
      9 Feb 2024, 10:19

      @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 9 Feb 2024, 10:24 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 9 Feb 2024, 10:30
      0
      • S StudentScripter
        9 Feb 2024, 10:24

        @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 9 Feb 2024, 10:30 last edited by Asperamanca 2 Sept 2024, 10:31
        #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 9 Feb 2024, 10:54
        3
        • A Asperamanca
          9 Feb 2024, 10:30

          @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 9 Feb 2024, 10:54 last edited by StudentScripter 2 Sept 2024, 11:01
          #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
            9 Feb 2024, 10:00

            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 9 Feb 2024, 11:16 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 9 Feb 2024, 11:35
            1
            • A Asperamanca
              9 Feb 2024, 11:16

              @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 9 Feb 2024, 11:35 last edited by StudentScripter 2 Sept 2024, 13:01
              #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 9 Feb 2024, 15:02
              0
              • S StudentScripter
                9 Feb 2024, 11:35

                @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 9 Feb 2024, 15:02 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 10 Feb 2024, 13:21
                2
                • A Asperamanca
                  9 Feb 2024, 15:02

                  @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 10 Feb 2024, 13:21 last edited by StudentScripter 2 Oct 2024, 13:44
                  #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 12 Feb 2024, 11:52
                  0
                  • S StudentScripter
                    10 Feb 2024, 13:21

                    @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 12 Feb 2024, 11:52 last edited by Asperamanca 2 Dec 2024, 11:53
                    #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 15 Feb 2024, 18:06
                    0
                    • A Asperamanca
                      12 Feb 2024, 11:52

                      @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 15 Feb 2024, 18:06 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

                      13/13

                      15 Feb 2024, 18:06

                      • Login

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