Reputation: 385
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
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