Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Pyside2 QListWidgetItem signal when exit editing even without changes
Forum Updated to NodeBB v4.3 + New Features

Pyside2 QListWidgetItem signal when exit editing even without changes

Scheduled Pinned Locked Moved Solved Qt for Python
13 Posts 3 Posters 1.8k Views 1 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.
  • J Offline
    J Offline
    JesusM97
    wrote on 12 May 2022, 08:20 last edited by
    #1

    Hello, I need to know when a user has finished editing a QListWidgetItem.
    I know there is a signal in QListWidget that emits when a item has changed but I want to recive the signal even if the item has not changed because I want to remove ItemIsEditable flag after editing it.

    How can I do it? I am using Pyside2

    Thanks!

    J 1 Reply Last reply 12 May 2022, 08:48
    0
    • J JesusM97
      13 May 2022, 09:25

      @JonB

      With what you have told me I have found a solution.
      I have the function renameItem() which is called when I select an item and I choose the action "Rename".
      Then I have the function rename_item_finished() which is called after editing finished.
      Instead of connecting the closeEditor signal to the function you told me, I can connect it to my custom function and pass the item being edited. Only one item can be selected in my list (I do not allow multiple selection) and, therefore, only one item can be edited at the same time.:

          def renameItem(self, list):
              print("Renaming")
              if list.selectedItems().__len__() > 0:
                  itemSelected = list.selectedItems()[0]
                  itemSelected.setFlags(itemSelected.flags() | Qt.ItemIsEditable)
                  list.editItem(itemSelected)
                  list.itemDelegate().closeEditor.connect(self.rename_item_finished(itemSelected))
      
          def rename_item_finished(self, item):
              print("Rename finished")
              item.setFlags(item.flags() & ~Qt.ItemIsEditable)
      

      I tested it and it seems working well. Thank you!

      J Online
      J Online
      JonB
      wrote on 13 May 2022, 09:33 last edited by
      #11

      @JesusM97 said in Pyside2 QListWidgetItem signal when exit editing even without changes:

      I tested it and it seems working well. Thank you!

      That is good :)

      However I am surprised that your list.itemDelegate().closeEditor.connect(self.rename_item_finished(itemSelected)) works at all!? Does that not call self.rename_item_finished(itemSelected) as you execute that connect() statement? My understanding is that it ought (a) call print("Rename finished") as you do the connect() and (b) not connect the signal to your slot? I would have expected you to have to write:

      list.itemDelegate().closeEditor.connect(lambda: self.rename_item_finished(itemSelected))
      

      No?

      J 1 Reply Last reply 13 May 2022, 09:54
      1
      • J JesusM97
        12 May 2022, 08:20

        Hello, I need to know when a user has finished editing a QListWidgetItem.
        I know there is a signal in QListWidget that emits when a item has changed but I want to recive the signal even if the item has not changed because I want to remove ItemIsEditable flag after editing it.

        How can I do it? I am using Pyside2

        Thanks!

        J Online
        J Online
        JonB
        wrote on 12 May 2022, 08:48 last edited by
        #2

        @JesusM97 said in Pyside2 QListWidgetItem signal when exit editing even without changes:

        I need to know when a user has finished editing a QListWidgetItem.

        How do you allow user to "edit a QListWidgetItem."? E.g. does the user have to double-click on an item, or what/how?

        1 Reply Last reply
        0
        • J Offline
          J Offline
          JesusM97
          wrote on 12 May 2022, 09:30 last edited by JesusM97 5 Dec 2022, 09:31
          #3

          With right click I show a QMenu with a QAction called "rename". When user triggers the action I enable Qt.ItemIsEditable flag and call to editItem().

          J 1 Reply Last reply 12 May 2022, 12:07
          0
          • J JesusM97
            12 May 2022, 09:30

            With right click I show a QMenu with a QAction called "rename". When user triggers the action I enable Qt.ItemIsEditable flag and call to editItem().

            J Online
            J Online
            JonB
            wrote on 12 May 2022, 12:07 last edited by JonB 5 Dec 2022, 12:07
            #4

            @JesusM97
            I don't see a way to know that editItem() has concluded and I don't see a signal emitted when that happens but not one of the signals for having changed the item. You might want to look through the source code (C++ on woboq, PySide is not relevant to this issue) if nobody gives you an answer.

            J 1 Reply Last reply 13 May 2022, 07:23
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 12 May 2022, 20:10 last edited by
              #5

              Hi,

              I would go with a custom QStyledIemDelegate and see what you can do with editorEvent.

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

              J 1 Reply Last reply 13 May 2022, 07:23
              1
              • J JonB
                12 May 2022, 12:07

                @JesusM97
                I don't see a way to know that editItem() has concluded and I don't see a signal emitted when that happens but not one of the signals for having changed the item. You might want to look through the source code (C++ on woboq, PySide is not relevant to this issue) if nobody gives you an answer.

                J Offline
                J Offline
                JesusM97
                wrote on 13 May 2022, 07:23 last edited by JesusM97
                #6

                @JonB
                Thanks for your answer, I found this code in C++:

                connect( delegate, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)), this, SLOT(...) );
                

                but I am still trying to tanslate it to Pyside2 becauase I dont know what I have to pass as first parameter to closeEditor function

                J 1 Reply Last reply 13 May 2022, 08:23
                0
                • S SGaist
                  12 May 2022, 20:10

                  Hi,

                  I would go with a custom QStyledIemDelegate and see what you can do with editorEvent.

                  J Offline
                  J Offline
                  JesusM97
                  wrote on 13 May 2022, 07:23 last edited by
                  #7

                  @SGaist
                  Thanks for your answer, I'm going to take a look at that and see what I get.

                  1 Reply Last reply
                  0
                  • J JesusM97
                    13 May 2022, 07:23

                    @JonB
                    Thanks for your answer, I found this code in C++:

                    connect( delegate, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)), this, SLOT(...) );
                    

                    but I am still trying to tanslate it to Pyside2 becauase I dont know what I have to pass as first parameter to closeEditor function

                    J Online
                    J Online
                    JonB
                    wrote on 13 May 2022, 08:23 last edited by JonB
                    #8

                    @JesusM97 said in Pyside2 QListWidgetItem signal when exit editing even without changes:

                    connect( delegate, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)), this, SLOT(...) );

                    Python connects look rather different and, to be fair, simpler:

                    self.delegate.closeEditor.connect(self.onCloseEditor)
                    
                    def onCloseEditor(self, editor, hint=NoHint):
                        print("Editor widget is:", editor, "EndEditHint is: ", hint)
                    

                    See https://doc.qt.io/qtforpython-5/PySide2/QtWidgets/QAbstractItemDelegate.html#PySide2.QtWidgets.PySide2.QtWidgets.QAbstractItemDelegate.closeEditor.

                    However, for your use case ("even if the item has not changed because I want to remove ItemIsEditable flag after editing it.") you want to get at the item in the list widget which has just been edited, so you can change its flag, correct? And I don't think you can do that from the editor variable passed by the closeEditor signal.

                    For that I think you need to earlier override @SGaist's editorEvent or QAbstractItemDelegate.createEditor(parent, option, index), both of which receive an index parameter identifying which item is being edited. That would need saving up (in a member variable), so that when you later receive the closeEditor signal you can use that index to find the item, and hence the QListWidgetItem whose flag you want to change.

                    J 2 Replies Last reply 13 May 2022, 09:24
                    2
                    • J JonB
                      13 May 2022, 08:23

                      @JesusM97 said in Pyside2 QListWidgetItem signal when exit editing even without changes:

                      connect( delegate, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)), this, SLOT(...) );

                      Python connects look rather different and, to be fair, simpler:

                      self.delegate.closeEditor.connect(self.onCloseEditor)
                      
                      def onCloseEditor(self, editor, hint=NoHint):
                          print("Editor widget is:", editor, "EndEditHint is: ", hint)
                      

                      See https://doc.qt.io/qtforpython-5/PySide2/QtWidgets/QAbstractItemDelegate.html#PySide2.QtWidgets.PySide2.QtWidgets.QAbstractItemDelegate.closeEditor.

                      However, for your use case ("even if the item has not changed because I want to remove ItemIsEditable flag after editing it.") you want to get at the item in the list widget which has just been edited, so you can change its flag, correct? And I don't think you can do that from the editor variable passed by the closeEditor signal.

                      For that I think you need to earlier override @SGaist's editorEvent or QAbstractItemDelegate.createEditor(parent, option, index), both of which receive an index parameter identifying which item is being edited. That would need saving up (in a member variable), so that when you later receive the closeEditor signal you can use that index to find the item, and hence the QListWidgetItem whose flag you want to change.

                      J Offline
                      J Offline
                      JesusM97
                      wrote on 13 May 2022, 09:24 last edited by JesusM97
                      #9
                      This post is deleted!
                      1 Reply Last reply
                      0
                      • J JonB
                        13 May 2022, 08:23

                        @JesusM97 said in Pyside2 QListWidgetItem signal when exit editing even without changes:

                        connect( delegate, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)), this, SLOT(...) );

                        Python connects look rather different and, to be fair, simpler:

                        self.delegate.closeEditor.connect(self.onCloseEditor)
                        
                        def onCloseEditor(self, editor, hint=NoHint):
                            print("Editor widget is:", editor, "EndEditHint is: ", hint)
                        

                        See https://doc.qt.io/qtforpython-5/PySide2/QtWidgets/QAbstractItemDelegate.html#PySide2.QtWidgets.PySide2.QtWidgets.QAbstractItemDelegate.closeEditor.

                        However, for your use case ("even if the item has not changed because I want to remove ItemIsEditable flag after editing it.") you want to get at the item in the list widget which has just been edited, so you can change its flag, correct? And I don't think you can do that from the editor variable passed by the closeEditor signal.

                        For that I think you need to earlier override @SGaist's editorEvent or QAbstractItemDelegate.createEditor(parent, option, index), both of which receive an index parameter identifying which item is being edited. That would need saving up (in a member variable), so that when you later receive the closeEditor signal you can use that index to find the item, and hence the QListWidgetItem whose flag you want to change.

                        J Offline
                        J Offline
                        JesusM97
                        wrote on 13 May 2022, 09:25 last edited by
                        #10

                        @JonB

                        With what you have told me I have found a solution.
                        I have the function renameItem() which is called when I select an item and I choose the action "Rename".
                        Then I have the function rename_item_finished() which is called after editing finished.
                        Instead of connecting the closeEditor signal to the function you told me, I can connect it to my custom function and pass the item being edited. Only one item can be selected in my list (I do not allow multiple selection) and, therefore, only one item can be edited at the same time.:

                            def renameItem(self, list):
                                print("Renaming")
                                if list.selectedItems().__len__() > 0:
                                    itemSelected = list.selectedItems()[0]
                                    itemSelected.setFlags(itemSelected.flags() | Qt.ItemIsEditable)
                                    list.editItem(itemSelected)
                                    list.itemDelegate().closeEditor.connect(self.rename_item_finished(itemSelected))
                        
                            def rename_item_finished(self, item):
                                print("Rename finished")
                                item.setFlags(item.flags() & ~Qt.ItemIsEditable)
                        

                        I tested it and it seems working well. Thank you!

                        J 1 Reply Last reply 13 May 2022, 09:33
                        0
                        • J JesusM97
                          13 May 2022, 09:25

                          @JonB

                          With what you have told me I have found a solution.
                          I have the function renameItem() which is called when I select an item and I choose the action "Rename".
                          Then I have the function rename_item_finished() which is called after editing finished.
                          Instead of connecting the closeEditor signal to the function you told me, I can connect it to my custom function and pass the item being edited. Only one item can be selected in my list (I do not allow multiple selection) and, therefore, only one item can be edited at the same time.:

                              def renameItem(self, list):
                                  print("Renaming")
                                  if list.selectedItems().__len__() > 0:
                                      itemSelected = list.selectedItems()[0]
                                      itemSelected.setFlags(itemSelected.flags() | Qt.ItemIsEditable)
                                      list.editItem(itemSelected)
                                      list.itemDelegate().closeEditor.connect(self.rename_item_finished(itemSelected))
                          
                              def rename_item_finished(self, item):
                                  print("Rename finished")
                                  item.setFlags(item.flags() & ~Qt.ItemIsEditable)
                          

                          I tested it and it seems working well. Thank you!

                          J Online
                          J Online
                          JonB
                          wrote on 13 May 2022, 09:33 last edited by
                          #11

                          @JesusM97 said in Pyside2 QListWidgetItem signal when exit editing even without changes:

                          I tested it and it seems working well. Thank you!

                          That is good :)

                          However I am surprised that your list.itemDelegate().closeEditor.connect(self.rename_item_finished(itemSelected)) works at all!? Does that not call self.rename_item_finished(itemSelected) as you execute that connect() statement? My understanding is that it ought (a) call print("Rename finished") as you do the connect() and (b) not connect the signal to your slot? I would have expected you to have to write:

                          list.itemDelegate().closeEditor.connect(lambda: self.rename_item_finished(itemSelected))
                          

                          No?

                          J 1 Reply Last reply 13 May 2022, 09:54
                          1
                          • J JonB
                            13 May 2022, 09:33

                            @JesusM97 said in Pyside2 QListWidgetItem signal when exit editing even without changes:

                            I tested it and it seems working well. Thank you!

                            That is good :)

                            However I am surprised that your list.itemDelegate().closeEditor.connect(self.rename_item_finished(itemSelected)) works at all!? Does that not call self.rename_item_finished(itemSelected) as you execute that connect() statement? My understanding is that it ought (a) call print("Rename finished") as you do the connect() and (b) not connect the signal to your slot? I would have expected you to have to write:

                            list.itemDelegate().closeEditor.connect(lambda: self.rename_item_finished(itemSelected))
                            

                            No?

                            J Offline
                            J Offline
                            JesusM97
                            wrote on 13 May 2022, 09:54 last edited by
                            #12

                            @JonB
                            You are right, it was calling self.rename_item_finished(itemSelected) as I was executing the connect() but, it doesn't take me out of edit mode. I can finish editing and then I can't rename again with double click. However, I will modify the function as you said to avoid problems. My QAction connects are defined in the same way:

                            removeAction.triggered.connect(lambda: self.removeItem(self.list))
                            renameAction.triggered.connect(lambda: self.renameItem(self.list))
                            
                            J 1 Reply Last reply 13 May 2022, 09:59
                            0
                            • J JesusM97
                              13 May 2022, 09:54

                              @JonB
                              You are right, it was calling self.rename_item_finished(itemSelected) as I was executing the connect() but, it doesn't take me out of edit mode. I can finish editing and then I can't rename again with double click. However, I will modify the function as you said to avoid problems. My QAction connects are defined in the same way:

                              removeAction.triggered.connect(lambda: self.removeItem(self.list))
                              renameAction.triggered.connect(lambda: self.renameItem(self.list))
                              
                              J Online
                              J Online
                              JonB
                              wrote on 13 May 2022, 09:59 last edited by
                              #13

                              @JesusM97
                              Yes, you can write connects in Python in one of two ways:

                              • object.signal.connect(self.slot) # note "self.slot", no "()"s
                              • object.signal.connect(lambda: self.slot(maybe-some-arguments)) # note "lambda:" required here to call "self.slot(...)" with "()"s
                              1 Reply Last reply
                              1

                              1/13

                              12 May 2022, 08:20

                              • Login

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