Skip to content
Advertisement

QCombobox in a QDataWidgetMapper does not update model when using QSortFilterProxyModel on QSqlRelationalTableModel

I have a setup that uses a QTableView with a QSqlRelationalTableModel and a QDataWidgetMapper to edit the values of the active row in the table view:

model = QRelationalTableModel(self, self.db)
model.setEditStrategy(QSqlTableModel.OnFieldChange)
model.setTable(table_name)

model.setRelation(i, relation_table, 'id', 'kurz'))

proxy_model = QSortFilterProxyModel(self)
proxy_model.setSourceModel(model)
view.setModel(proxy_model)

cb.setModel(model.relationModel(i))
cb.setModelColumn(model.relationModel(i).fieldIndex('kurz'))

mapper = QDataWidgetMapper(self)
mapper.setModel(proxy_model)
mapper.setItemDelegate(QSqlRelationalDelegate(self))
mapper.addMapping(cb, i)

Everything works as expected when I set the QRelationalTableModel instance as the view’s model. But when I use the proxy model, as above, changes in comboboxes do not update the view. But they show the correct data. And it’s only the comboboxes, that do not work with the proxy model. Cells from Date and lineedit widgets get updated correctly.

So I wonder if I miss something here. So far I didn’t find anything in the docs that covers this problem.

Advertisement

Answer

I found a solution. I had to subclass QSqlRelationalDelegate and reimplement setModelData:

class MapperItemDelegate(QSqlRelationalDelegate):

    def __init__(self, parent):
        QSqlRelationalDelegate.__init__(self, parent)

    def setModelData(self, editor, model, index):
        if type(model) == QSortFilterProxyModel and type(editor) == QComboBox:
            index = model.mapToSource(index)
            model = model.sourceModel()
        return QSqlRelationalDelegate.setModelData(self, editor, model, index)

and then:

mapper.setItemDelegate(MapperItemDelegate(mapper))

Took me some hours to find out. A thank to @musicamante for syntax correction.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement