Leogout
Leogout

Reputation: 1247

Update multiple Qt models based on a single data source

I want to trigger multiple models updates and thus multiple views updates based on a raw data source update (like a list of objects). How would the mapping between the data and the multiple models work ?

For example:

I have a list of multiple Measurements which contain attributes like size, color and weight

Then I trigger an update on my raw data. It can come from one of the connected models mentionned above or from an outside update. How to prepend this change to all my associated models ?

I am using python with Pyside2 but the answer can be in C++

Upvotes: 0

Views: 902

Answers (1)

Leogout
Leogout

Reputation: 1247

So as @Frank Osterfeld said in his comment, it is possible to store all your data in a model (QAbstractTableModel in my case) and then filter out the columns that you don't need in your respective views.

For this I've used a QSortFilterProxyModel and overrided the filterAcceptsColumn() method.

Here is an example:

class MyModel(QAbstractTableModel):
    def __init__(self):
        super().__init__()
        self.data = []
    ... # here are all the things you usually define in an abstract model

class MyProxyModelA(QSortFilterProxyModel):
    def filterAcceptsColumn(self, source_column: int, source_parent: QModelIndex) -> bool:
        """ This filters any column that returns true """
        return source_column != 2

class MyProxyModelB(QSortFilterProxyModel):
    def filterAcceptsColumn(self, source_column: int, source_parent: QModelIndex) -> bool:
        """ This filters any column that returns true """
        return source_column == 2

And in my views:

model = MyModel()  # I put this here for the sake of this example

class MyWidgetA(QWidget):
    def __init__(self):
        super().__init__()

        self.ui = Ui_Form()
        self.ui.setupUi(self)

        self.table = QTableView()

        self.proxy = MyProxyModelA()
        self.proxy.setSourceModel(model)

        self.table.setModel(self.proxy)

        self.ui.layout.addWidget(self.table)


class MyWidgetB(QWidget):
    def __init__(self):
        super().__init__()

        self.ui = Ui_Form()
        self.ui.setupUi(self)

        self.table = QTableView()

        self.proxy = MyProxyModelB()
        self.proxy.setSourceModel(model)

        self.table.setModel(self.proxy)

        self.ui.layout.addWidget(self.table)

And now you can benefit from the automatic sync of your model and your views whenever you modify it through MyWidgetA or MyWidgetB

Upvotes: 1

Related Questions