Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update QAbstractTableModel and QTableView after sorting the data source?

I have a custom data structure that I want to display in a PyQt application using a QTableView. I'm using a subclass of QAbstractTableModel to communicate with the data. The data structure itself is in a separate module and knows nothing about PyQt.

Displaying and editing the data with the QTableView works, but now I'd like to sort the data and then update the model and view.

After reading the Qt documentation for QAbstractTableModel and its ancestor QAbstractItemModel, my first approach was to try this:

class MyModel(QtCore.QAbstractTableModel):
    __init__(self, data_structure):
        super().__init__()
        self.data_structure = data_structure

    # ...

    def sort_function(self):
        self.layoutAboutToBeChanged.emit()
        # custom_sort() is built into the data structure
        self.data_structure.custom_sort()
        self.layoutChanged.emit()

However, this fails to update the view. I also tried emitting a dataChanged signal on all of the data being used by the model, but this failed to update the view as well.

I did some further research. If I understand correctly, the problem is that the QPersistentModelIndexes in the model are not getting updated, and the solution would be to manually update them somehow.

Is there a better way to do this? If not, how would I go about updating them (preferably without having to write a new sort function that tracks every index change)?

like image 262
Nick Ulle Avatar asked Jan 24 '12 08:01

Nick Ulle


1 Answers

There was a bug in the custom_sort() function. After fixing it, the approach I described here works.

class MyModel(QtCore.QAbstractTableModel):
    __init__(self, data_structure):
        super().__init__()
        self.data_structure = data_structure

    # ...

    def sort_function(self):
        self.layoutAboutToBeChanged.emit()
        # custom_sort() is built into the data structure
        self.data_structure.custom_sort()
        self.layoutChanged.emit()
like image 178
Nick Ulle Avatar answered Nov 04 '22 15:11

Nick Ulle