0

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?

wooly81
  • 15
  • 3
  • Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. – Community Jul 28 '22 at 03:39

2 Answers2

0

this doesn't perfectly answer your question for python but I made an example of a ColumnView with gtk4-rs (rust) https://github.com/gtk-rs/gtk4-rs/pull/1111

I use ListStore.append(...) for many items (structs) and then have columnview factory functions that pick the element from the struct to display in a particular column

Colin D
  • 2,822
  • 1
  • 31
  • 38
0

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 [])
Dodezv
  • 266
  • 2
  • 8