Bertramp
Bertramp

Reputation: 385

Why does my QStandardItemModel itemFromIndex method return None? (index invalid)

I am trying to make a listview with checkboxes that checks the selected boxes when the enter/return key is pressed. I do this with an override of the eventfilter for my MainWindow (yes I ought to subclass it, but I couldn't get that working)

In the eventfilter i get a None value returned from the itemFromIndex method even though I just passed the index through a .isValid() without problems. Obviously i am missing something, but i can't figure it out - is it looking at completely different indices? is the model not updated?

Any advice on alternate approaches are welcome

This is the method I use to fill the model (QStandardItemModel) with items, it's only called when i load a file.

    def update_siNLV(self,names,model):

        model.clear()

        for name in names:            
            item = Qg.QStandardItem(name)
            item.setCheckState(Qc.Qt.Unchecked)
            item.setCheckable(True)
            model.appendRow(item)

This is from the init method where I create a variable for the selectionmodel and install the eventfilter on my QListView

    self.sigInSelection = self.siNLV.selectionModel()
    self.siNLV.installEventFilter(self)

The eventFilter method looks like this and the filtering part of the method works (I've made it print the selected indices with press on the enter key)

    def eventFilter(self,receiver,event):
        if event.type() == QtCore.QEvent.KeyPress:
            if event.key() == QtCore.Qt.Key_Return or event.key() == Qc.Qt.Key_Enter:

                indexes = self.sigInSelection.selectedIndexes()

                for index in indexes:
                    if index.isValid():                        
                        print(str(index.row())+" "+str(index.column()))                                   
                        item = self.sigInModel.itemFromIndex(index)
                        item.setCheckState(qtCore.Qt.Checked)                     
                return True

    return super(form,self).eventFilter(receiver,event)

Upvotes: 1

Views: 2252

Answers (1)

strubbly
strubbly

Reputation: 3477

As discussed in the comments:

The indices returned by QItemSelectionModel.selectedIndexes() come from the view and relate to the connection between the view and its immediate model. The identity of that model can be found by calling QModelIndex.model() and in this case it is not the model that you want: it is instead a proxy model that is in-between your desired QStandardItemModel and the view.

To get to the model you want you need to use QAbstractProxyModel.mapToSource(). So you might use code something like this:

source_index = self.proxy.mapToSource(index)
item = self.sigInModel.itemFromIndex(source_index)

More generally you could traverse an arbitrary proxy structure and avoid this hard-coded usage of a single known proxy by code something like:

proxy_model = index.model()
while proxy_model != self.sigInModel:
    index = proxy_model.mapToSource(index)
    proxy_model = index.model()
item = self.sigInModel.itemFromIndex(index)

But this is probably overkill in this case where you know there is a simple single proxy.

Upvotes: 2

Related Questions