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 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!

    JonBJ 1 Reply Last reply
    0
    • J JesusM97

      @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!

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on 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
      1
      • J JesusM97

        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!

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on 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 last edited by JesusM97
          #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().

          JonBJ 1 Reply Last reply
          0
          • J JesusM97

            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().

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #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
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on 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
              1
              • JonBJ JonB

                @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 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

                JonBJ 1 Reply Last reply
                0
                • SGaistS SGaist

                  Hi,

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

                  J Offline
                  J Offline
                  JesusM97
                  wrote on 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

                    @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

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on 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
                    2
                    • JonBJ JonB

                      @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 last edited by JesusM97
                      #9
                      This post is deleted!
                      1 Reply Last reply
                      0
                      • JonBJ JonB

                        @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 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!

                        JonBJ 1 Reply Last reply
                        0
                        • J JesusM97

                          @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!

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on 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
                          1
                          • JonBJ JonB

                            @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 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))
                            
                            JonBJ 1 Reply Last reply
                            0
                            • J JesusM97

                              @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))
                              
                              JonBJ Offline
                              JonBJ Offline
                              JonB
                              wrote on 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

                              • Login

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