[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