Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dmzoneill/74033698f65a5a1539d686452a73dce8 to your computer and use it in GitHub Desktop.
Save dmzoneill/74033698f65a5a1539d686452a73dce8 to your computer and use it in GitHub Desktop.

Revisions

  1. dmzoneill created this gist May 3, 2024.
    146 changes: 146 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,146 @@
    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)