[kwlug-disc] Filtering on Two Columns in Gtk+ v3 and Python.

John Driezen jdriezen at sympatico.ca
Sat Jun 5 05:13:08 EDT 2021


I am attempting to extend the demo program at 
https://python-gtk-3-tutorial.readthedocs.io/en/latest/treeview.html to 
filter on two columns and sort the resulting filtered rows. The tutorial 
suggests the following: "Instances of Gtk.TreeModelFilter|| can be 
stacked one onto another, to use multiple filters on the same model (in 
the same way you’d use “AND” clauses in a SQL request)."   However the 
tutorial does not give an example of this, and my google fu is failing 
to find an example online.  My attempt at filtering by two columns 
follows.  The code works when filtering by programming language, or when 
filtering by year.  I don't know how to filter by both programming 
language and year.  Suggestions anyone?

""" Sorted and Filtered TreeView Demo Program. Filters on two columns. """
import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

# list of tuples for each software
SOFTWARE_LIST = [
     ("Firefox", 2002, "C++"),
     ("Eclipse", 2004, "Java"),
     ("Pitivi", 2004, "Python"),
     ("Netbeans", 1996, "Java"),
     ("Chrome", 2008, "C++"),
     ("Filezilla", 2001, "C++"),
     ("Bazaar", 2005, "Python"),
     ("Git", 2005, "C"),
     ("Linux Kernel", 1991, "C"),
     ("GCC", 1987, "C"),
     ("Frostwire", 2004, "Java"),
     ("Homebank", 1995, "C"),
     ("Tellico", 2001, "C++"),
     ("gLabels", 2001, "C++"),
     ("Deluge", 2007, "Python"),
]

class TreeViewFilterWindow(Gtk.Window):
     """ TreeViewFilterWindow class """
     def __init__(self):
         Gtk.Window.__init__(self, title="Treeview Filter Demo")
         self.set_border_width(10)

         # Setting up the self.grid in which the elements are to be 
positioned
         self.grid = Gtk.Grid()
         self.grid.set_column_homogeneous(True)
         self.grid.set_row_homogeneous(True)
         self.add(self.grid)

         # Creating the ListStore model
         self.software_liststore = Gtk.ListStore(str, int, str)
         for software_ref in SOFTWARE_LIST:
             self.software_liststore.append(list(software_ref))

         self.current_filter_language = None
         self.current_filter_year = None

         # Creating the filters, feeding it with the liststore model
         self.language_filter = self.software_liststore.filter_new()
         #self.year_filter = self.software_liststore.filter_new()
         # Setting the filter functions
self.language_filter.set_visible_func(self.language_filter_func)
         #self.year_filter.set_visible_func(self.year_filter_func)

         # Creating the treeview, using the sorted filter as a model and 
adding the columns
         self.sortedandfilteredtree = 
Gtk.TreeModelSort(model=self.language_filter)
         #self.sortedandfilteredtree = 
Gtk.TreeModelSort(model=self.year_filter)
         self.sortedtreeview = 
Gtk.TreeView.new_with_model(self.sortedandfilteredtree)
         for i, column_title in enumerate(["Software", "Release Year", 
"Programming Language"]):
             renderer = Gtk.CellRendererText()
             column = Gtk.TreeViewColumn(column_title, renderer, text=i)
             column.set_sort_order(Gtk.SortType.ASCENDING)
             column.set_sort_column_id(i)
             self.sortedtreeview.append_column(column)

         # Creating buttons to filter by programming language and 
setting up their events
         self.language_buttons = list()
         for prog_language in ["Java", "C", "C++", "Python", "None"]:
             button = Gtk.Button(label=prog_language)
             self.language_buttons.append(button)
             button.connect("clicked", 
self.on_language_selection_button_clicked)

         # Creating buttons to filter by release year and setting up 
their events
         self.year_buttons = list()
         for year in [1987, 1991, 1995, 1996, 2001, 2002, 2004, 2005, 
2007, 2008, "None"]:
             button = Gtk.Button(label=year)
             self.year_buttons.append(button)
             button.connect("clicked", 
self.on_year_selection_button_clicked)

         # Setting up the layout, putting the treeview in a 
scrollwindow, and the buttons in a
         # set_row_homogeneous
         self.scrollable_treelist = Gtk.ScrolledWindow()
         self.scrollable_treelist.set_vexpand(True)
         self.grid.attach(self.scrollable_treelist, 0, 0, 8, 10)
         self.grid.attach_next_to(self.language_buttons[0], 
self.scrollable_treelist,
                                  Gtk.PositionType.BOTTOM, 1, 1)

         # Layout language selection buttons
         for i, button in enumerate(self.language_buttons[1:]):
             self.grid.attach_next_to(button, self.language_buttons[i], 
Gtk.PositionType.RIGHT, 1, 1)

         self.grid.attach_next_to(self.year_buttons[0], 
self.language_buttons[0],
                                  Gtk.PositionType.BOTTOM, 1, 1)

         # Layout year selection buttons
         for i, button in enumerate(self.year_buttons[1:]):
             self.grid.attach_next_to(button, self.year_buttons[i], 
Gtk.PositionType.RIGHT, 1, 1)

         self.scrollable_treelist.add(self.sortedtreeview)

         self.show_all()

     def language_filter_func(self, model, iter, data):
         """ Tests if the language in the row is the one in the filter """
         if self.current_filter_language is None or 
self.current_filter_language == "None":
             return True
         else:
             return model[iter][2] == self.current_filter_language

     def year_filter_func(self, model, iter, data):
         """ Tests if the year in the row is the one in the filter. """
         if self.current_filter_year is None or self.current_filter_year 
== "None":
             return True
         else:
             return model[iter][1] == self.current_filter_year

     def on_language_selection_button_clicked(self, widget):
         """ Called on any of the language button clicks """
         # Set the current language filter to the button's 
scrollable_treelist
         self.current_filter_language = widget.get_label()
         print("%s language selected!" % self.current_filter_language)
         # Update the filter, which updates the view in turn
         self.language_filter.refilter()

     def on_year_selection_button_clicked(self, widget):
         """ Called on any of the year selection button clicks. """
         if (widget.get_label() == "None"):
             self.current_filter_year = None
         else:
             self.current_filter_year = int(widget.get_label())
         print("year %s selected!" % self.current_filter_year)
         self.year_filter.refilter()

TV_WIN = TreeViewFilterWindow()
TV_WIN.connect("destroy", Gtk.main_quit)
TV_WIN.show_all()
Gtk.main()

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://kwlug.org/pipermail/kwlug-disc_kwlug.org/attachments/20210605/95fd381a/attachment.htm>


More information about the kwlug-disc mailing list