Question

How can I get an interactive search (the search called by pressing Ctrl-f or /) to iterate over collapsed rows of a Gtk.TreeView?

For example if I wanted to search for "Second in Four" without expanding "Row Four" first in the following code:

from gi.repository import Gtk

class Main(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Recursive Search")

        self.set_default_size(200, 200)

        self.treestore = Gtk.TreeStore(str, str)

        treeiter = self.treestore.append(None, ["Row One", ""])
        self.treestore.append(treeiter, ["Row Two", "First in One"])
        self.treestore.append(treeiter, ["Row Tree", "Second in One"])

        treeiter = self.treestore.append(None, ["Row Four", ""])
        self.treestore.append(treeiter, ["Row Five", "First in Four"])
        self.treestore.append(treeiter, ["Row Six", "Second in Four"])

        treeiter = self.treestore.append(None, ["Row Seven", ""])
        self.treestore.append(treeiter, ["Row Eight", "First in Seven"])
        self.treestore.append(treeiter, ["Row Nine", "Second in Seven"])

        treeview = Gtk.TreeView(model=self.treestore)

        renderer_text = Gtk.CellRendererText()
        column_text = Gtk.TreeViewColumn(cell_renderer=renderer_text, text=0)
        treeview.append_column(column_text)
        column_text = Gtk.TreeViewColumn(cell_renderer=renderer_text, text=1)
        treeview.append_column(column_text)

        treeview.set_search_column(1)

        treeview.set_headers_visible(False)

        self.add(treeview)

win = Main()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
Was it helpful?

Solution

You can use Gtk.Treeview.set_search_equal_func() for this:

    def __init__(self):
        ...
        treeview.set_search_equal_func(self.search_function)
        self.treeview = treeview

    def search_function(self, model, column, key, rowiter):
        row = model[rowiter]
        if key.lower() in list(row)[column-1].lower():
            return False # Search matches

        # Search in child rows.  If one of the rows matches, expand the row so that it will be open in later checks.
        for inner in row.iterchildren():
            if key.lower() in list(inner)[column-1].lower():
                self.treeview.expand_to_path(row.path)
                break
        else:
             self.treeview.collapse_row(row.path)

        return True # Search does not match

I would recommend gnome.org for documentation on Gtk. It doesn't have all of the latest updates, but it has easy-to-read and easy-to-find documentation on many of the Gtk classes and functions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top