TreeModelFilter

The TreeModelFilter objects provides a way to filter the data displayed in a ListStore or TreeStore via a function, which returns whether the data is shown or not.

Constructor

The TreeModelFilter is typically constructed from an existing model:

treemodelfilter = model.filter_new()

It can however be constructed itself, with the model being derived from the filter:

treemodelfilter = Gtk.TreeModelFilter()

Methods

A function is attached to the TreeModelFilter which returns True or False depending on whether the row is to be displayed or not. The function is called for each row in the model, and when False is returned, the row is NOT displayed. The function is set via:

treemodelfilter.set_visible_func(function, data)

The data specifies the data which is being displayed in the TreeModelFilter.

The TreeModelFilter can be refiltered using the method:

treemodelfilter.refilter()

In some cases, it may be useful to use columns within the data model which indicate whether a row should be displayed. Setting the column type to a Boolean type, the column can be declared with:

treemodelfilter.set_visible_column(column)

The column value should be set to the number of the column containing the visibility information. When the row is set to True it is displayed.

When retrieving the selected item from the viewing widget, it will return a TreeIter or TreePath for the filter. These need to be converted to correctly access the underlying model:

treemodelfilter.convert_iter_to_child_iter(treeiter)
treemodelfilter.convert_path_to_child_path(treepath)

A convenience function can be used to return the model being filtered:

treemodefilter.get_model()

Example

Below is an example of a TreeModelFilter:

#!/usr/bin/env python3

from gi.repository import Gtk

products = (("Apple", "Fruit", "£0.20"),
            ("Bleach", "Cleaning", "£1.20"),
            ("Bird Seed", "Pets", "£2.50"),
            ("Banana", "Fruit", "£0.35"),
            ("Beer", "Alcohol", "£2.75"),
            ("Cornflakes", "Cereal", "£1.10"),
            ("Pineapple", "Fruit", "£0.75"),
           )

class TreeModelFilter(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.connect("destroy", Gtk.main_quit)

        grid = Gtk.Grid()
        grid.set_row_spacing(5)
        self.add(grid)

        scrolledwindow = Gtk.ScrolledWindow()
        scrolledwindow.set_vexpand(True)
        scrolledwindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)
        grid.attach(scrolledwindow, 0, 0, 1, 1)

        liststore = Gtk.ListStore(str, str, str)
        self.treemodelfilter = liststore.filter_new()
        self.treemodelfilter.set_visible_func(self.filter_visible, products)

        self.combobox = Gtk.ComboBoxText()
        self.combobox.append_text("All")
        self.combobox.set_active(0)
        self.combobox.connect("changed", self.on_category_changed)
        grid.attach(self.combobox, 0, 1, 1, 1)

        for product in products:
            liststore.append(product)

            self.combobox.append_text(product[1])

        treeview = Gtk.TreeView()
        treeview.set_model(self.treemodelfilter)
        scrolledwindow.add(treeview)

        cellrenderertext = Gtk.CellRendererText()
        treeviewcolumn = Gtk.TreeViewColumn("Product", cellrenderertext, text=0)
        treeview.append_column(treeviewcolumn)
        treeviewcolumn = Gtk.TreeViewColumn("Category", cellrenderertext, text=1)
        treeview.append_column(treeviewcolumn)
        treeviewcolumn = Gtk.TreeViewColumn("Price", cellrenderertext, text=2)
        treeview.append_column(treeviewcolumn)

    def on_category_changed(self, combobox):
        self.treemodelfilter.refilter()

    def filter_visible(self, model, treeiter, data):
        show = False

        if model[treeiter][1] == self.combobox.get_active_text():
            show = True
        elif self.combobox.get_active_text() == "All":
            show = True

        return show

window = TreeModelFilter()
window.show_all()

Gtk.main()

Download: TreeModelFilter