Created
May 3, 2024 18:56
-
-
Save dmzoneill/74033698f65a5a1539d686452a73dce8 to your computer and use it in GitHub Desktop.
Pygtk4 ColumnView
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
import string | |
import gi | |
gi.require_version("Gtk", "4.0") | |
from gi.repository import Gio, GLib, GObject, Gtk # noqa | |
class DataObject(GObject.GObject): | |
__gtype_name__ = "DataObject" | |
text = GObject.Property(type=GObject.TYPE_STRING, default="") | |
number = GObject.Property(type=GObject.TYPE_FLOAT, default=0) | |
truefalse = GObject.Property(type=GObject.TYPE_BOOLEAN, default=False) | |
def __init__(self, text, number, truefalse=False): | |
super().__init__() | |
self.text = text | |
self.number = number | |
self.truefalse = truefalse | |
class MyApp(Gtk.Application): | |
def __init__(self): | |
super().__init__(application_id="org.gtk.Example") | |
self.list_view = Gtk.ColumnView() | |
self.store = Gio.ListStore.new(DataObject) | |
self.sort_model = Gtk.SortListModel.new(self.store) | |
self.selection = Gtk.SingleSelection.new(self.sort_model) | |
self.list_view.set_model(self.selection) | |
self.update_timer = None | |
@staticmethod | |
def to_str(bind, from_value): | |
return str(from_value) | |
def update_data(self): | |
print("Updating data...") | |
for item in self.store: | |
random_text = "".join( | |
random.choices(string.ascii_uppercase + string.digits, k=5) | |
) | |
random_number = random.randint(5555, 9999) | |
item.set_property("text", random_text) | |
item.set_property("number", random_number) | |
item.set_property("truefalse", random.choice([True, False])) | |
# Return True to keep the timeout | |
return True | |
def init_columnview(self): | |
properties = [prop.name for prop in DataObject.list_properties()] | |
for x in range(10): | |
self.store.append(DataObject("entry", 0.0)) | |
for i, property_name in enumerate(properties): | |
factory = Gtk.SignalListItemFactory() | |
factory.connect("setup", self.setup, property_name) | |
factory.connect("bind", self.bind, property_name) | |
column = Gtk.ColumnViewColumn.new(f"column{i+1:02}", factory) | |
# Create a Gtk.Expression for the property | |
property_expression = Gtk.PropertyExpression.new(DataObject, None, property_name) | |
# Create a Gtk.Sorter based on the property type | |
property_type = DataObject.find_property(property_name).value_type.fundamental | |
if property_type == GObject.TYPE_STRING: | |
sorter = Gtk.StringSorter.new(property_expression) | |
elif property_type == GObject.TYPE_FLOAT: | |
sorter = Gtk.NumericSorter.new(property_expression) | |
elif property_type == GObject.TYPE_BOOLEAN: | |
sorter = Gtk.NumericSorter.new(property_expression) | |
# Set the sorter on the column | |
column.set_sorter(sorter) | |
self.list_view.append_column(column) | |
self.update_timer = GLib.timeout_add_seconds(1, self.update_data) | |
def setup(self, widget, item, property_name): | |
"""Setup the widget to show in the Gtk.Listview""" | |
def setup_when_idle(): | |
obj = item.get_item() | |
property_type = obj.find_property(property_name).value_type | |
if property_type == GObject.TYPE_BOOLEAN: | |
widget_type = Gtk.CheckButton | |
else: | |
widget_type = Gtk.Label | |
widget = widget_type() | |
item.set_child(widget) | |
GLib.idle_add(setup_when_idle) | |
def bind(self, widget, item, property_name): | |
"""bind data from the store object to the widget""" | |
def bind_when_idle(): | |
child = item.get_child() | |
obj = item.get_item() | |
property_type = obj.find_property(property_name).value_type | |
if property_type == GObject.TYPE_BOOLEAN: | |
widget_property = "active" | |
obj.bind_property( | |
property_name, | |
child, | |
widget_property, | |
GObject.BindingFlags.SYNC_CREATE, | |
) | |
else: | |
widget_property = "label" | |
# child.bind_property(widget_property, obj, property_name, | |
# GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.BIDIRECTIONAL) | |
obj.bind_property( | |
property_name, | |
child, | |
widget_property, | |
GObject.BindingFlags.SYNC_CREATE, | |
self.to_str, | |
) | |
GLib.idle_add(bind_when_idle) | |
def do_activate(self): | |
win = Gtk.ApplicationWindow( | |
application=self, | |
title="Gtk4 is Awesome !!!", | |
default_height=400, | |
default_width=400, | |
) | |
sw = Gtk.ScrolledWindow() | |
self.init_columnview() | |
sw.set_child(self.list_view) | |
win.set_child(sw) | |
win.present() | |
app = MyApp() | |
app.run(None) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment