Pyside2 QListWidgetItem signal when exit editing even without changes
-
wrote on 12 May 2022, 08:20 last edited by
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!
-
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!
wrote on 13 May 2022, 09:33 last edited by@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 callself.rename_item_finished(itemSelected)
as you execute thatconnect()
statement? My understanding is that it ought (a) callprint("Rename finished")
as you do theconnect()
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?
-
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!
wrote on 12 May 2022, 08:48 last edited by@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?
-
wrote on 12 May 2022, 09:30 last edited by JesusM97 5 Dec 2022, 09:31
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().
-
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().
wrote on 12 May 2022, 12:07 last edited by JonB 5 Dec 2022, 12:07@JesusM97
I don't see a way to know thateditItem()
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. -
Hi,
I would go with a custom QStyledIemDelegate and see what you can do with editorEvent.
-
@JesusM97
I don't see a way to know thateditItem()
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.wrote on 13 May 2022, 07:23 last edited by 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
-
Hi,
I would go with a custom QStyledIemDelegate and see what you can do with editorEvent.
-
@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
wrote on 13 May 2022, 08:23 last edited by JonB@JesusM97 said in Pyside2 QListWidgetItem signal when exit editing even without changes:
connect( delegate, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)), this, SLOT(...) );
Python
connect
s 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)
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 thecloseEditor
signal.For that I think you need to earlier override @SGaist's
editorEvent
orQAbstractItemDelegate.createEditor(parent, option, index)
, both of which receive anindex
parameter identifying which item is being edited. That would need saving up (in a member variable), so that when you later receive thecloseEditor
signal you can use thatindex
to find the item, and hence theQListWidgetItem
whose flag you want to change. -
@JesusM97 said in Pyside2 QListWidgetItem signal when exit editing even without changes:
connect( delegate, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)), this, SLOT(...) );
Python
connect
s 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)
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 thecloseEditor
signal.For that I think you need to earlier override @SGaist's
editorEvent
orQAbstractItemDelegate.createEditor(parent, option, index)
, both of which receive anindex
parameter identifying which item is being edited. That would need saving up (in a member variable), so that when you later receive thecloseEditor
signal you can use thatindex
to find the item, and hence theQListWidgetItem
whose flag you want to change.wrote on 13 May 2022, 09:24 last edited by JesusM97This post is deleted! -
@JesusM97 said in Pyside2 QListWidgetItem signal when exit editing even without changes:
connect( delegate, SIGNAL(closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)), this, SLOT(...) );
Python
connect
s 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)
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 thecloseEditor
signal.For that I think you need to earlier override @SGaist's
editorEvent
orQAbstractItemDelegate.createEditor(parent, option, index)
, both of which receive anindex
parameter identifying which item is being edited. That would need saving up (in a member variable), so that when you later receive thecloseEditor
signal you can use thatindex
to find the item, and hence theQListWidgetItem
whose flag you want to change.wrote on 13 May 2022, 09:25 last edited byWith 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!
-
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!
wrote on 13 May 2022, 09:33 last edited by@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 callself.rename_item_finished(itemSelected)
as you execute thatconnect()
statement? My understanding is that it ought (a) callprint("Rename finished")
as you do theconnect()
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?
-
@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 callself.rename_item_finished(itemSelected)
as you execute thatconnect()
statement? My understanding is that it ought (a) callprint("Rename finished")
as you do theconnect()
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?
wrote on 13 May 2022, 09:54 last edited by@JonB
You are right, it was callingself.rename_item_finished(itemSelected)
as I was executing theconnect()
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))
-
@JonB
You are right, it was callingself.rename_item_finished(itemSelected)
as I was executing theconnect()
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))
wrote on 13 May 2022, 09:59 last edited by@JesusM97
Yes, you can writeconnect
s 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/13