updating QFilterProxyModel once the source model changes



  • 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)
    0_1515441319065_Screenshot from 2018-01-08 19:53:31.png

    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.


  • Lifetime Qt Champion

    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:

    1. Get the proxy to filter correctly. I'd suggest KRecursiveFilterProxyModel but since you are on Python you'll need to subclass QSortFilterProxyModel and reimplement filteracceptrow to accept the parent if a child is included in the filter

    2. 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 Foo in 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

    -A
    -Arm
    -Ark
    -B
    -Bell
    -Bark
    -Bar

    suppose you type B, The treeview should be
    -B
    -Bell
    -Bark
    -Bar

    Now when you click on Bar, then the code fecthes the children of Bar and expands
    the tree as follows

    -B
    -Bell
    -Bark
    +Bar
    --Foo
    --Test1
    --Test2

    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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.