Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dmzoneill/19a4fbd799f1e5bcc050ddb4b0a65403 to your computer and use it in GitHub Desktop.
Save dmzoneill/19a4fbd799f1e5bcc050ddb4b0a65403 to your computer and use it in GitHub Desktop.
sorted listed model gtk4
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.column_view = Gtk.ColumnView()
self.store = Gio.ListStore.new(DataObject)
self.update_timer = None
@staticmethod
def to_str(bind, from_value):
return str(from_value)
def update_data(self):
print("Updating data...")
for i, item in enumerate(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.column_view.append_column(column)
sorter = Gtk.ColumnView.get_sorter(self.column_view)
self.sort_model = Gtk.SortListModel.new(self.store, sorter)
self.selection = Gtk.SingleSelection.new(self.sort_model)
self.column_view.set_model(self.selection)
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.column_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