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. How to dehighlight single and multiple items from QGraphicsScene in Qt?
Forum Updated to NodeBB v4.3 + New Features

How to dehighlight single and multiple items from QGraphicsScene in Qt?

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 2 Posters 475 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.
  • T Offline
    T Offline
    tushu
    wrote on last edited by tushu
    #1

    I have a QGraphicsScene which has 100+ items. Sometimes I need to highlight and dehighlight multiple items.

    Here is the code:

    HighlightObject(QEvent* event)
    {
       //Finding object under cursor
       QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
       QPointF mousePoint = _view->mapToScene(mouseEvent->pos());
       QGraphicsItem* itemUnderClick = scene->itemAt(mousePoint, QTransform());
       
       QGraphicsPathItem* polylineItem = qgraphicsitem_cast<QGraphicsPathItem*>(itemUnderClick);
        if (polylineItem ) {
            //polylineItem ->setFlag(QGraphicsItem::ItemIsSelectable);//I have set this flag while drawing polyline.
            polylineItem ->setSelected(true);
            QPen mPen(Qt::SolidLine);
            mPen.setWidth(1);
            polylineItem ->setPen(mPen);
          }
    }
    

    My scene has 1 button which refreshes the scene. (which dehighlight all the items in the scene)

    Refresh()
      {
         foreach (QGraphicsItem* currentItem, scene->items()) 
        {
          myPoly* pItem = qgraphicsitem_cast<myPoly*>(currentItem);
          if (pItem)  
          {
              pItem->setSelected(false);
              pItem->setPen(QPen(QColor("red")); // original color of polyline is red.
          }
       }
    

    Above code works fine. But my scene has many elements so this Refresh() becomes costly.
    So in Refresh() I tried :

    foreach (QGraphicsItem* currentItem, scene->selectedItems())
    

    But above does not work for multiple selection. It means if I have selected 2 itms from the scene, and now I want to dehighlight both of them, then it always dehighlight 1 item.
    I tried to print the value of

    scene->selectedItems().size() => 1
    

    So I want to :

    1) Dehighlight multiple object.
    2) To dehighlight 1 object, I do not want to iterate over all scene.
    
    JonBJ 1 Reply Last reply
    0
    • T tushu

      I have a QGraphicsScene which has 100+ items. Sometimes I need to highlight and dehighlight multiple items.

      Here is the code:

      HighlightObject(QEvent* event)
      {
         //Finding object under cursor
         QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
         QPointF mousePoint = _view->mapToScene(mouseEvent->pos());
         QGraphicsItem* itemUnderClick = scene->itemAt(mousePoint, QTransform());
         
         QGraphicsPathItem* polylineItem = qgraphicsitem_cast<QGraphicsPathItem*>(itemUnderClick);
          if (polylineItem ) {
              //polylineItem ->setFlag(QGraphicsItem::ItemIsSelectable);//I have set this flag while drawing polyline.
              polylineItem ->setSelected(true);
              QPen mPen(Qt::SolidLine);
              mPen.setWidth(1);
              polylineItem ->setPen(mPen);
            }
      }
      

      My scene has 1 button which refreshes the scene. (which dehighlight all the items in the scene)

      Refresh()
        {
           foreach (QGraphicsItem* currentItem, scene->items()) 
          {
            myPoly* pItem = qgraphicsitem_cast<myPoly*>(currentItem);
            if (pItem)  
            {
                pItem->setSelected(false);
                pItem->setPen(QPen(QColor("red")); // original color of polyline is red.
            }
         }
      

      Above code works fine. But my scene has many elements so this Refresh() becomes costly.
      So in Refresh() I tried :

      foreach (QGraphicsItem* currentItem, scene->selectedItems())
      

      But above does not work for multiple selection. It means if I have selected 2 itms from the scene, and now I want to dehighlight both of them, then it always dehighlight 1 item.
      I tried to print the value of

      scene->selectedItems().size() => 1
      

      So I want to :

      1) Dehighlight multiple object.
      2) To dehighlight 1 object, I do not want to iterate over all scene.
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @tushu said in How to dehighlight single and multiple items from QGraphicsScene in Qt?:

      foreach (QGraphicsItem* currentItem, scene->selectedItems())

      This principle ought work, but the problem may be (I don't know, I haven't tried) that this list changes dynamically, e.g. as you unhighlight the first item the second item becomes the first item but your loop then moves onto what was the third item which is now second, skipping what was second that is now first!

      You could try taking a copy of scene->selectedItems() so that it does not change and iterate through that. Or use the "lazy trick" I sometimes do for this sort of "remove from iterating list" by counting down from the end to the beginning of the list, like:

      for (int i = scene->selectedItems().size() - 1; i >= 0; i--)
          scene->selectedItems()[i].setSelected(false);
      

      If you want to deselect all selected items quickly don't forget there is QGraphicsScene::clearSelection()!

      If you have a single graphics item pointer you want deselected you can of course just deselect that directly without any iteration.

      T 1 Reply Last reply
      1
      • JonBJ JonB

        @tushu said in How to dehighlight single and multiple items from QGraphicsScene in Qt?:

        foreach (QGraphicsItem* currentItem, scene->selectedItems())

        This principle ought work, but the problem may be (I don't know, I haven't tried) that this list changes dynamically, e.g. as you unhighlight the first item the second item becomes the first item but your loop then moves onto what was the third item which is now second, skipping what was second that is now first!

        You could try taking a copy of scene->selectedItems() so that it does not change and iterate through that. Or use the "lazy trick" I sometimes do for this sort of "remove from iterating list" by counting down from the end to the beginning of the list, like:

        for (int i = scene->selectedItems().size() - 1; i >= 0; i--)
            scene->selectedItems()[i].setSelected(false);
        

        If you want to deselect all selected items quickly don't forget there is QGraphicsScene::clearSelection()!

        If you have a single graphics item pointer you want deselected you can of course just deselect that directly without any iteration.

        T Offline
        T Offline
        tushu
        wrote on last edited by
        #3

        @JonB Thank for your reply.
        I tried what you have suggested. But it always shows

        scene->selectedItems().size() = 1
        

        So I used

        vector<QGraphicsItem*> currentSelectedObject;
        

        And when I select object, I pushed it into currentSelectedObject and iterate over it when I want to deselect , selected items.

        I tried slot QGraphicsScene::clearSelection() in above example but I could not implement it properly.
        Can you help me in that ?

        JonBJ 1 Reply Last reply
        0
        • T tushu

          @JonB Thank for your reply.
          I tried what you have suggested. But it always shows

          scene->selectedItems().size() = 1
          

          So I used

          vector<QGraphicsItem*> currentSelectedObject;
          

          And when I select object, I pushed it into currentSelectedObject and iterate over it when I want to deselect , selected items.

          I tried slot QGraphicsScene::clearSelection() in above example but I could not implement it properly.
          Can you help me in that ?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @tushu
          No, because I don't know what you are doing wrong, or what you are expecting that isn't happening. For example, if scene->selectedItems().size() == 1 then there is only only selected object, yet you claim there are many. QGraphicsScene::clearSelection() clears all selections, so I don't know what "I could not implement it properly" means or what your problem is or what it is not doing.

          I assume you would mention if you were using QGraphicsItemGroups which might affect this.

          T 1 Reply Last reply
          0
          • JonBJ JonB

            @tushu
            No, because I don't know what you are doing wrong, or what you are expecting that isn't happening. For example, if scene->selectedItems().size() == 1 then there is only only selected object, yet you claim there are many. QGraphicsScene::clearSelection() clears all selections, so I don't know what "I could not implement it properly" means or what your problem is or what it is not doing.

            I assume you would mention if you were using QGraphicsItemGroups which might affect this.

            T Offline
            T Offline
            tushu
            wrote on last edited by
            #5

            @JonB Thank you for your response.

            You are right. I am using QGraphicsItemGroups for my digital gates ( AND,NAND,NOT etc ) which contains lines , arcs and circles

            If you want to know, how I created QGraphicsItemGroups please visit this question, I have written code there.

            https://stackoverflow.com/questions/73165655/my-paint-is-not-working-for-all-items-in-scene?noredirect=1#comment129227329_73165655

            ( If you want I can explain that code here also )

            ( I did not give complete code bcoz, in polylines I was facing issue so I showed that code only. )
            Complete HighlightObject() code :

            * HighlightObject(QEvent* event)
            {
               //Finding object under cursor
               QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
               QPointF mousePoint = _view->mapToScene(mouseEvent->pos());
               QGraphicsItem* itemUnderClick = scene->itemAt(mousePoint, QTransform());
               QGraphicsPathItem* polylineItem = qgraphicsitem_cast<QGraphicsPathItem*>(itemUnderClick);
                if (polylineItem ) 
              {
                    //polylineItem ->setFlag(QGraphicsItem::ItemIsSelectable);//I have set this 
                   flag while drawing polyline.
                    polylineItem ->setSelected(true);
                   QPen mPen(Qt::SolidLine);
                    mPen.setWidth(1);
                    polylineItem ->setPen(mPen);
            }
            else
            {
                 QGraphicsItemGroup* gItem = qgraphicsitem_cast<QGraphicsItemGroup*>(itemUnderClick);
                             if (gItem) {
                                 gItem->setFlag(QGraphicsItem::ItemIsSelectable);//need to remove as it is done while creating
                                 gItem->setSelected(true);  
            }           
            }
            

            And Refresh() code :

            std::cout<<"Before  Refresh size =  : "<<_scene->selectedItems().size()<<std::endl;
            //foreach (QGraphicsItem* currentItem, _scene->items()) {
                    for (int i = _scene->selectedItems().size() - 1; i >= 0; i--){
                        myPoly* pItem = qgraphicsitem_cast<myPoly*>(_scene->selectedItems()[i]);
                        if (pItem ) {
                            pItem->setSelected(false);
                            QPen mPen;
                            mPen.setWidth(1);
                            pItem->setPen(mPen);
                            pItem->setPen(QPen(QColor("red"), 1));
                        } else {
                            QGraphicsItemGroup* sItem = dynamic_cast<QGraphicsItemGroup*>(_scene->selectedItems()[i]);
                            if (sItem) {
                                sItem->setSelected(false);
                            }
                        }
                    }
                }
            
            JonBJ 1 Reply Last reply
            0
            • T tushu

              @JonB Thank you for your response.

              You are right. I am using QGraphicsItemGroups for my digital gates ( AND,NAND,NOT etc ) which contains lines , arcs and circles

              If you want to know, how I created QGraphicsItemGroups please visit this question, I have written code there.

              https://stackoverflow.com/questions/73165655/my-paint-is-not-working-for-all-items-in-scene?noredirect=1#comment129227329_73165655

              ( If you want I can explain that code here also )

              ( I did not give complete code bcoz, in polylines I was facing issue so I showed that code only. )
              Complete HighlightObject() code :

              * HighlightObject(QEvent* event)
              {
                 //Finding object under cursor
                 QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
                 QPointF mousePoint = _view->mapToScene(mouseEvent->pos());
                 QGraphicsItem* itemUnderClick = scene->itemAt(mousePoint, QTransform());
                 QGraphicsPathItem* polylineItem = qgraphicsitem_cast<QGraphicsPathItem*>(itemUnderClick);
                  if (polylineItem ) 
                {
                      //polylineItem ->setFlag(QGraphicsItem::ItemIsSelectable);//I have set this 
                     flag while drawing polyline.
                      polylineItem ->setSelected(true);
                     QPen mPen(Qt::SolidLine);
                      mPen.setWidth(1);
                      polylineItem ->setPen(mPen);
              }
              else
              {
                   QGraphicsItemGroup* gItem = qgraphicsitem_cast<QGraphicsItemGroup*>(itemUnderClick);
                               if (gItem) {
                                   gItem->setFlag(QGraphicsItem::ItemIsSelectable);//need to remove as it is done while creating
                                   gItem->setSelected(true);  
              }           
              }
              

              And Refresh() code :

              std::cout<<"Before  Refresh size =  : "<<_scene->selectedItems().size()<<std::endl;
              //foreach (QGraphicsItem* currentItem, _scene->items()) {
                      for (int i = _scene->selectedItems().size() - 1; i >= 0; i--){
                          myPoly* pItem = qgraphicsitem_cast<myPoly*>(_scene->selectedItems()[i]);
                          if (pItem ) {
                              pItem->setSelected(false);
                              QPen mPen;
                              mPen.setWidth(1);
                              pItem->setPen(mPen);
                              pItem->setPen(QPen(QColor("red"), 1));
                          } else {
                              QGraphicsItemGroup* sItem = dynamic_cast<QGraphicsItemGroup*>(_scene->selectedItems()[i]);
                              if (sItem) {
                                  sItem->setSelected(false);
                              }
                          }
                      }
                  }
              
              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @tushu said in How to dehighlight single and multiple items from QGraphicsScene in Qt?:

              You are right. I am using QGraphicsItemGroups

              It would really have helped if you had stated this. Maybe that affects how the count of selected items works? Maybe you have to go into the members of the group?

              T 1 Reply Last reply
              0
              • JonBJ JonB

                @tushu said in How to dehighlight single and multiple items from QGraphicsScene in Qt?:

                You are right. I am using QGraphicsItemGroups

                It would really have helped if you had stated this. Maybe that affects how the count of selected items works? Maybe you have to go into the members of the group?

                T Offline
                T Offline
                tushu
                wrote on last edited by
                #7
                This post is deleted!
                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