updating QFilterProxyModel once the source model changes
bloogs last edited by bloogs
Hi I am creating a dialog for objects with children, a QTreeview with a QlineEdit for filtering. When the dialog comes up initially, it looks like (no.1)
the code looks like below. I've summarised it with just the important bits
#These are global so can be referenced from any function. and all set #when i initialise my diaglog. model=QtGui.QStandardItemModel() treeview=QtGui.QTreeview() proxymodel=QtGui.QSortFilterProxyModel(treeview) treeview.setmodel(proxymodel) proxymodel.setSourceModel(model) def initialise_treeview(self): #This builds the treeview with a list of root nodes only root_nodes=["Apple","Ardvark","Ankle","Bee","Bark","Bar","Carrot"]# a list of root nodes for objects in root_nodes: item=QtGui.QStandardItem(objects) model.appendRow(item)
No.2 shows the treeview being filtered when the user types into the LineEdit text box
#When a user types into the search field the Treeview gets filtered via the proxymodel QtCore.QObject.connect(LineEdit,QtCore.Signal("TextChanged(QString)")),update_filter) def update_filter(self,text): #filter the model based on the text in the qlineedit proxymodel.setFilterRegExp(LineEdit.text());
Once a user selects an item in the treeview (No. 3, where Bar has been selected). The code should fetch all of the selected items children, add them to the model, and finally expand the selected node to show all the child items (No. 4)
#update_treeview function is called to add children to the selected item QtCore.QObject.connect(treeview.selectionModel(),QtCore.Signal("currentChanged(QModelIndex,QmodelIndex)")),update_treeview) def update_treeview(self,currentindex,previousindex): sourcemodel_index=proxymodel.mapToSource(currentindex) parent_item=QtGui.QStandardItem() #get the item from the source model parent_item=model.itemFromIndex(sourcemodel_index) for childitem in list_of_children: file_item=QtGui.QStandardItem(str(childitem)) model.appendRow(file_item) treeview.expand(currentindex) #this doesn't work when proxymodel has been filtered
So far I have most of this working. Actually all of it. Except the expanding of the treeview, when there has been some filtering.
I have it working when NO filter has been applied, but once the treeview's list is filtered its a bit hit and miss i.e the treeview is not always expanded at the right node.
How can I ensure that the treeview expands at the correct index so that when the folder list has been filtered and files added to the filtered list. How can I ensure that the treeview is expanded to the right location. I'm using python 2.7,Qt 4.8 on windows.
Hi and welcome to devnet,
Are you locked to Qt 4 ? If not then please consider updating to Qt 5. Qt 4 has reached end of life since some times now and should not be used for new projects.
One of the benefits would be to get QFileSystemModel which seems to be doing some of what you want for you.
@SGaist Thanks for posting. Yes I am locked into Qt 4.8, QFilesystemModel is a good suggestion but I need a more flexible solution, that extends beyond a filesystem, so for example if I had json file entries which had nodes that referenced other text files which themselves referred out to other files. I was looking for a general solution that would work both for folders and files as well as a nested structure.
There are 2 separate problems here:
Get the proxy to filter correctly. I'd suggest KRecursiveFilterProxyModel but since you are on Python you'll need to subclass
QSortFilterProxyModeland reimplement filteracceptrow to accept the parent if a child is included in the filter
Get the correct index to expand. This is easy to implement in code but it's not clear what you want to expand
How do I keep the proxymodel in sync with the source model
You don't have do do anything, everything is already implemented
@VRonin You are right. My problem is with the second part. How do you get the correct index to expand to, once you've updated the model.
Say your model is:
- A -- Foo -- Bar - B -- Foo --- Test1 --- Test2 -- Bar --- Test1 --- Test2
and you type
Fooin the filter.
What would you like your view to expand?
@VRonin hmm I see you have Foo in A and B. Let me modify the question a little.
my model is more like
suppose you type B, The treeview should be
Now when you click on Bar, then the code fecthes the children of Bar and expands
the tree as follows
The initial filter is based on the top level entries(those with a single -)
I'm sorry but I still don't get how you would like it to look