Search code examples
qtpyqt4qstandarditemmodel

Change text of QStandardItem when editing starts


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.


Solution

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