pepeday
pepeday

Reputation: 97

Implementing filterAcceptsRows for filtering on a foreign key

I've found several answers to my question below but I can't seem to work out how to implement them in my case.

What I'm trying to do is connect a ComboBox to a QTableView, where the int id from the selected row of the ComboBox will be used to filter a Foreign Key of the model attached to a QTableView.

Let's say we have a personnel table with a person_company_fk foreign key column. This table is displayed in a QTableView through a model. The model is parsed though a filter, subclassed from QSortFilterProxyModel.

I've connected

self.currentIndexChanged.connect(self.personnelFilteredModel.FilterData(company_id))

so that any change in selection in the ComboBox sends the ID to the filtered model.

My problem is that the model does not refresh, and even though everything is connected, the QTableView does not change (no errors either). I believe my problem lies with how I'm calling dataChanged.emit(). By the way, if I set the self.fkFilter to a value in the __init__, the model displays the filtered rows.

Can you help out?

class CustomFilterModel(QtCore.QSortFilterProxyModel):
    def __init__(self):
        super(CustomFilterModel,self).__init__()
        self.fkColumnIndex=None
        self.nameColumnIndex=None
        self.fkFilter=None
        self.setDynamicSortFilter(True)

    def FilterData(self,fk):
        self.fkFilter=fk
        x=self.rowCount()
        y=self.columnCount()
        self.dataChanged.emit(self.index(0,0),self.index(x,y))

    def filterAcceptsRow(self, source_row:int, source_parent:QtCore.QModelIndex) -> bool:
        if (self.fkFilter !=None) and (self.fkColumnIndex !=None):
            x=self.createIndex(source_row,self.fkColumnIndex)
            j=int(self.sourceModel().data(x))
            if j==self.fkFilter:
                return True
            else:
                return False
        else:
            return True

Upvotes: 2

Views: 325

Answers (1)

eyllanesc
eyllanesc

Reputation: 243907

You have to call the invalidateFilter method for the filter to apply.

def FilterData(self,fk):
    self.fkFilter = fk
    self.invalidateFilter()

On the other hand the filterAcceptsRow method can be improved:

def filterAcceptsRow(self, source_row:int, source_parent:QtCore.QModelIndex) -> bool:
    if self.fkFilter and self.fkColumnIndex:
        ix = self.sourceModel().index(source_row, self.fkColumnIndex)
        text = ix.data()
        return text == self.fkFilter
    return True

Upvotes: 1

Related Questions