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