I'm converting a Python (3.10) application from GTK3 to GTK4, and I would like to move away from TreeView
/CellRenderer
usage, and try to use ColumnView
instead. I've read the documentation on GTK4's new list widgets, read their blog post about them, searched for examples, and am still quite confused.
As I understand it, a ColumnView
has a single model (i.e. Gtk.SingleSelection
), which itself is based on a GListModel
(i.e. Gio.ListStore
). Gio.ListStore
does not accept a list, like a Gtk.ListStore
does, so my question is, how do I store data for multiple columns, when the model (Gio.ListStore) doesn't accept a list?
You have to define your own Gobject.Object
to put into the Gio.ListStore
and then make your own factory to get those items. For example, I have a custom object defined as follows:
class FamilieRow(GObject.Object):
familie: str
anzahl: int
def __init__(self, familie: str, anzahl: int):
super().__init__()
self.familie = familie
self.anzahl = anzahl
The Gio.ListStore
then stores those items:
ls = Gio.ListStore()
ls.append(FamilieRow("Steffens", 15))
To populate the row familie
the factory is defined as
factory = Gtk.SignalListItemFactory()
factory.connect("setup", lambda _fact, item:
item.set_child(Gtk.Label(halign=Gtk.Align.START))
factory.connect("bind", lambda _fact, item:
item.get_child().set_label(item.get_item().familie))
col_f = Gtk.ColumnViewColumn(
title="Familie",
factory=factory,
)
If you wanted to change more than just the label, it could be inconvenient to use a lambda. Then you could let the custom object itself set up the widget by defining
factory.bind("bind", lambda _fact, item: item.get_item().bind_familie(item.get_child()))
and defining a bind_familie
method on your row object
class FamilieRow(GObject.Object):
...
def bind_familie(self, label: Gtk.Label, column: str):
label.set_label(self.familie)
label.set_style_classes(["big"] if self.anzahl > 40 else [])