Using Qt4's model/view framework, I have a list of items displayed as "Foo (38 bars)". I want to make the text editable, but when the user starts editing, I want the control to just show "Foo" (the name), and then to reinstate the extra info "(38 bars)" when editing is complete.
I think I can work out how to add the info back, but is there a way to change the text of the item when editing starts?
The model is a QStandardItemModel, and the items are fairly trivial subclasses of QStandardItem. They are displayed primarily in a QListView.
The UI is written in PyQt, and I'd prefer not to dive into C++ just for this, but I'll do my best to translate C++ solutions if they appear.
After @Chris put me on the right track, I found this note in the docs for QStandardItem:
The default implementation treats Qt::EditRole and Qt::DisplayRole as referring to the same data.
So I needed to override the method QStandardItem.data()
. My Python code looked like this:
def data(self, role=QtCore.Qt.UserRole+1):
if role == QtCore.Qt.DisplayRole:
return "{} ({} bars)".format(self.name, len(self.ds))
return super().data(role) # Fall back to the default method
On the model's itemChanged
signal, I updated the .name attribute I'm using:
def update_name(self):
self.name = self.data(QtCore.Qt.EditRole)
Finally, the number of "bars" can be changed elsewhere, and this should trigger any views to update the item. So after changing that, I called the item.emitDataChanged()
method (docs).
With this done, it seems to be working as intended.