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 delete all QTreeWidgetItems having the same text as selected QTreeWidgetItem?
QtWS25 Last Chance

How to delete all QTreeWidgetItems having the same text as selected QTreeWidgetItem?

Scheduled Pinned Locked Moved General and Desktop
qtreewidgetqtreewidgetitem
24 Posts 2 Posters 10.2k 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.
  • WDR_937W Offline
    WDR_937W Offline
    WDR_937
    wrote on last edited by
    #1

    Hi... I am new to Qt and I am learning slowly. I have learnt how to delete the selected item in the tree widget individually one by one. However, now I want to delete all the items in the widget having the same text (QString) as the selected item, including the selected item. How would I do this?

    Here's an example,

    Tree Widgets

    If I delete the selected item bullets, all top level items containing bullets as parent or child must be deleted. How can I do this? Additionally, how do I put the deleted items from the left tree widget to the right tree widget? I tried doing this but whether I delete a child or a parent, it is coming back as parent in the next widget. Here's how I did it,

    void Widget::on_Delete_Button_clicked()
    {
        QTreeWidgetItem* Resource = new QTreeWidgetItem(ui->Unusable_Resources_Tree);
    
        Resource->setText(0, ui->Usable_Resources_Tree->currentItem()->text(0));
    
        delete ui->Usable_Resources_Tree->currentItem();
    }
    

    How would I do this where irrespective of whether I delete a child or parent, the entire tree will be deleted and recreated in the next widget thereby preserving the hierarchy of the tree? Please help me with this. Thank you.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Rather than delete, you should use takeTopLevelItem to get the item and then add it to your other QTreeWidget

      Hope it helps

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      WDR_937W 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        Rather than delete, you should use takeTopLevelItem to get the item and then add it to your other QTreeWidget

        Hope it helps

        WDR_937W Offline
        WDR_937W Offline
        WDR_937
        wrote on last edited by WDR_937
        #3

        @SGaist OK... does takeTopLevelItem preserve the hierarchy of the tree i.e. does it take the tree including parent and child? Also, any idea on how I would remove all the trees containing the selected string? Please help. Thanks.

        EDIT: I tried the takeTopLevelItem() and it worked. It preserves the entire tree hierarchy without any problem. However, I still have to remove the multiple trees.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          So if you have something like:

          -item1
          --item2
          ---item3

          if item3 contains the searched string then item1 and item2 should also follow item3 ?

          For the search part, findItems is your friend.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          WDR_937W 1 Reply Last reply
          0
          • SGaistS SGaist

            So if you have something like:

            -item1
            --item2
            ---item3

            if item3 contains the searched string then item1 and item2 should also follow item3 ?

            For the search part, findItems is your friend.

            WDR_937W Offline
            WDR_937W Offline
            WDR_937
            wrote on last edited by
            #5

            @SGaist Well, yeah... But that's what the takeTopLevelItem is supposed to do. I want to delete multiple trees containing the string. In my example above, bullets is the parent in bullets --> ore but it is the child in hangun --> bullets and turret-->bullets. So, if I delete bullets in any one of these three trees, all three trees must be deleted. Any idea how I can do that?

            P. S. : The takeTopLevelItem removes the selected tree but only if the parent is selected and its index is given as argument to takeTopLevelItem. If a child is selected or nothing is selected, it is removing the top most tree by default (index = 0). How would I fix this? Is there a way of checking whether the selected item is a child or parent and then passing that tree's index as argument? Also, how should I not make it remove the tree by default if unselected? Please tell me this. Thank you very much for your help so far.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              The quick way is to go from the child back to the top level item using parent. Then you can use the top level number and do what you want. The fact that an item is selected or not is of no importance when using takeTopLevelItem.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              WDR_937W 1 Reply Last reply
              0
              • SGaistS SGaist

                The quick way is to go from the child back to the top level item using parent. Then you can use the top level number and do what you want. The fact that an item is selected or not is of no importance when using takeTopLevelItem.

                WDR_937W Offline
                WDR_937W Offline
                WDR_937
                wrote on last edited by
                #7

                @SGaist OK... So, Child_Item->parent(), right? I'll do that! Thanks for telling me that.

                @SGaist said:

                The fact that an item is selected or not is of no importance when using takeTopLevelItem.

                If that's the case, how would I disable it when nothing is selected? My button click is removing the top most tree by default, which is not supposed to happen. A boolean check flag perhaps, which checks selected or not... Is there a predefined method for that?

                I am going to implement the multiple tree deletion with findItems and see how it goes. Thanks for your help, SGaist.

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Just disable the button/action you want to click to perform the action.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  WDR_937W 1 Reply Last reply
                  0
                  • SGaistS SGaist

                    Just disable the button/action you want to click to perform the action.

                    WDR_937W Offline
                    WDR_937W Offline
                    WDR_937
                    wrote on last edited by
                    #9

                    @SGaist If I do that, how would I implement the button click again when the item is selected? I am checking for selection inside the button click function. Is this not the right way to do it?

                    1 Reply Last reply
                    0
                    • WDR_937W Offline
                      WDR_937W Offline
                      WDR_937
                      wrote on last edited by WDR_937
                      #10

                      OK... So, I managed to make the widget remove items only when an item is selected. It does not remove the first tree by default if unselected. I used Resource->isSelected(). However, I am still working on how to remove the tree if the child is selected as this works only for parent. Secondly, this unselected condition works if there a trees existing in the widget. If the widget is empty, the application is crashing. Why is that happening? Here's what I did.

                      void Widget::on_Delete_Button_clicked()
                      {
                          QTreeWidgetItem* Resource = ui->Usable_Resources_Tree->currentItem();
                      
                          if(Resource->isSelected())
                          {
                              ui->Usable_Resources_Tree->takeTopLevelItem(ui->Usable_Resources_Tree->currentIndex().row());
                      
                              ui->Unusable_Resources_Tree->addTopLevelItem(Resource);
                      
                              Resource->setExpanded(true);
                          }
                      }
                      

                      I think the currentItem() is causing the crash. How would I fix this? Please tell me this. Thank you.

                      EDIT: Fixed it. Thank you. It works perfectly. Although, I still have to figure out the multiple tree removal. However, most of my question has been answered. :-)

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        Rather than checking if you have anything selected and thus having a button that might to nothing (which is never a good thing for your users) use the selectionChanged signal and enable/disable the button based on the emptiness of the selection.

                        For the multiple tree removal, work from your child up to the topLevelItem. I currently haven't seen any option to do it without a loop on parent until you get an item without parent but that one should work.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        WDR_937W 1 Reply Last reply
                        0
                        • SGaistS SGaist

                          Rather than checking if you have anything selected and thus having a button that might to nothing (which is never a good thing for your users) use the selectionChanged signal and enable/disable the button based on the emptiness of the selection.

                          For the multiple tree removal, work from your child up to the topLevelItem. I currently haven't seen any option to do it without a loop on parent until you get an item without parent but that one should work.

                          WDR_937W Offline
                          WDR_937W Offline
                          WDR_937
                          wrote on last edited by WDR_937
                          #12

                          @SGaist

                          @SGaist said:

                          Rather than checking if you have anything selected and thus having a button that might to nothing (which is never a good thing for your users) use the selectionChanged signal and enable/disable the button based on the emptiness of the selection.

                          Yes, that might be the more optimal approach. Although, how would I use the selectionChanged to deselect an item when clicked on empty space?

                          I already figured out the multiple tree removal problem, but thanks for your solution. It's very similar to what you suggested. I used findItems to return the list of all items containing that string and iterating through that list, I'm checking if the returned item is a child or parent. If it's a parent, I'm removing it directly. If it's a child, I am removing the child's parent. It's working perfectly. However, I believe this could cause anomalies if there are multiple sub children i.e. if the child's parent is not a top level item. Since my program has parents with only one child, I guess it's fine.

                          Nevertheless, thank you very much for your help, SGaist. I really appreciate it.

                          1 Reply Last reply
                          0
                          • SGaistS Offline
                            SGaistS Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            You don't, that signal just tells you that something has changed selection wise. Reaction to a click on an empty space is handled by the widget.

                            If you have the child deeper than the second level, then yes you would need to go back up to the top level item.

                            You're welcome !

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            WDR_937W 1 Reply Last reply
                            0
                            • SGaistS SGaist

                              You don't, that signal just tells you that something has changed selection wise. Reaction to a click on an empty space is handled by the widget.

                              If you have the child deeper than the second level, then yes you would need to go back up to the top level item.

                              You're welcome !

                              WDR_937W Offline
                              WDR_937W Offline
                              WDR_937
                              wrote on last edited by
                              #14

                              @SGaist Is this the right way of doing it?

                              connect(ui->Usable_Resource_Tree, SIGNAL(ui->Usable_Resource_Tree->selectionModel()->selectionChanged()), this, SLOT(Disable_Button()));
                              
                              void Disable_Button()
                              {
                                  ui->Delete_Button->setEnabled(false);
                              }
                              

                              I haven't tested this. But I'm pretty sure something is definitely not right here. Please tell me whether my code is correct. Thanks.

                              1 Reply Last reply
                              0
                              • SGaistS Offline
                                SGaistS Offline
                                SGaist
                                Lifetime Qt Champion
                                wrote on last edited by
                                #15

                                No it's not,

                                connect(ui->Usable_Resource_Tree->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(updateDeleteButton(QItemSelection, QItemSelection)));
                                
                                void updateDeleteButton(const QItemSelection &selected, const QItemSelection &deselected)
                                {
                                    ui->Delete_Button->setEnabled(selected.size() > 0);
                                }
                                

                                Interested in AI ? www.idiap.ch
                                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                WDR_937W 1 Reply Last reply
                                0
                                • SGaistS SGaist

                                  No it's not,

                                  connect(ui->Usable_Resource_Tree->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(updateDeleteButton(QItemSelection, QItemSelection)));
                                  
                                  void updateDeleteButton(const QItemSelection &selected, const QItemSelection &deselected)
                                  {
                                      ui->Delete_Button->setEnabled(selected.size() > 0);
                                  }
                                  
                                  WDR_937W Offline
                                  WDR_937W Offline
                                  WDR_937
                                  wrote on last edited by
                                  #16

                                  @SGaist OK... So, I implemented what you posted here. It's working with selecting the items and is also being deselected when the item is removed. However, the clicking on empty space thing is still not implemented. How should this be implemented? Should I manually check for it or is it done automatically by the signal so that all I should do is just call it?

                                  The deselected variable is not being used, so I set it to Q_UNUSED. Is it needed anywhere? Also, since I am calling this signal/slot, do I need to check for Item->isSelected() later on in my delete button slot? Why I ask this, is because the program crashed earlier before I even implemented Item->isSelected(). That is why I implemented it.

                                  Finally, I am encountering two anomalous behaviors:-

                                  1. The selectionChanged() is deselecting on removing the child items, but for parent items, it is by default selecting the next parent in the widget. How to disable this?

                                  2. Sometimes, instead of graying out and flattening out on disabling, the delete button does not flatten out and becomes blue like it is when highlighted by the mouse. The text, however, grays out. It stays like this until it is enabled. This is only cosmetic as the button is still disabled. But it looks weird. Any way to fix this?

                                  My apologies if I asked too many questions. I just want to solve this tree problem. Please bear with me. Thank you. :-)

                                  1 Reply Last reply
                                  0
                                  • SGaistS Offline
                                    SGaistS Offline
                                    SGaist
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #17

                                    IIRC, you need to reimplement keyPressEvent and call clearSelection in it for that.

                                    Q_UNUSED is the right tool, deselected is not needed in that case.

                                    Since I don't know how you are currently performing the delete I can't comment on that one.

                                    1. Before performing the delete, gather all informations, clear the selection, perform the deletion
                                    2. Haven't seen that one happen

                                    Interested in AI ? www.idiap.ch
                                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                    WDR_937W 1 Reply Last reply
                                    0
                                    • SGaistS SGaist

                                      IIRC, you need to reimplement keyPressEvent and call clearSelection in it for that.

                                      Q_UNUSED is the right tool, deselected is not needed in that case.

                                      Since I don't know how you are currently performing the delete I can't comment on that one.

                                      1. Before performing the delete, gather all informations, clear the selection, perform the deletion
                                      2. Haven't seen that one happen
                                      WDR_937W Offline
                                      WDR_937W Offline
                                      WDR_937
                                      wrote on last edited by
                                      #18

                                      @SGaist said:

                                      IIRC, you need to reimplement keyPressEvent and call clearSelection in it for that.

                                      Do you mean QMouseEvent? Because I am clicking on empty space, not pressing any keys. Unless, the keyPressEvent is also used in this case, for which I don't know. Also, how would I know whether I am clicking on empty space or an item? Same selection.size > 0? Please clarify.

                                      @SGaist said:

                                      Since I don't know how you are currently performing the delete I can't comment on that one.

                                      Here's what I'm doing,

                                      QTreeWidgetItem *Resource = From_Tree->currentItem();
                                      
                                      if(Resource != NULL)
                                      	{
                                      		if(Resource->isSelected())
                                      		{
                                      			From_Tree->takeTopLevelItem(From_Tree->indexOfTopLevelItem(Resource));
                                      		}
                                      	}
                                      

                                      I remember why I implemented the isSelected(). When clicked, the button was removing the first item by default if nothing was selected. Since I am disabling the button completely when nothing is selected, I don't think I'll need this. Correct me if I'm wrong. Thanks.

                                      1 Reply Last reply
                                      0
                                      • SGaistS Offline
                                        SGaistS Offline
                                        SGaist
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #19

                                        mousePressEvent indeed… Use itemAt to see if you have something under the mouse

                                        You should rather user selectedItems

                                        Interested in AI ? www.idiap.ch
                                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                        WDR_937W 1 Reply Last reply
                                        0
                                        • SGaistS SGaist

                                          mousePressEvent indeed… Use itemAt to see if you have something under the mouse

                                          You should rather user selectedItems

                                          WDR_937W Offline
                                          WDR_937W Offline
                                          WDR_937
                                          wrote on last edited by WDR_937
                                          #20

                                          @SGaist said:

                                          mousePressEvent indeed… Use itemAt to see if you have something under the mouse

                                          Alright, thanks. I'll look into that. I'll see how it goes. If I hit any roadblock again, I'll ask here.

                                          @SGaist said:

                                          You should rather user selectedItems

                                          Are you talking about the QTreeWidgetItem *Resource = From_Tree->currentItem() part of my code?

                                          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