Trying to set a Gtk.ColumnView's width after size allocation has occurred

Hi all. I’ll start with my use-case. I’m building a Gtk.ColumnView with columns that can either be fixed with, or proportionately sized.

For example, I might have the 1st column storing a small integer, and only ever set to a fixed width of 120. Then I might add another 2 columns that I want to take up the rest of the available space, in a 30:70 ratio, due to the nature of the data that’s being entered.

I have all the logic to figure out the required column widths, based on a total available width. In gtk3 I used to be able to connect to the “size_allocate” signal and implement my column resizing logic there. I’ve been trying to port this to gtk4 for a long time ( see Do_size_allocate in gtk4 ) but haven’t had any success.

Am I on the right track with implementing the do_size_allocate method? Is there some example code that implements this method?

Hi,

The do_size_allocate allows a widget to place its children within. You get the widget’s size as parameter, and shall call size_allocate() on each children with their coordinated relative to the parent widget.

Something like this:


    def do_size_allocate(self, width, height, baseline):   # override
        """Size allocation handler."""
        rect = Gdk.Rectangle()
        # First child has a 120px fixed width
        rect.x, rect.y, rect.width, rect.height = 0, 0, 120, height
        self.child1.size_allocate(rect, baseline)
        # Second child takes 30%
        remaining_width = width - 120
        child2_width = remaining_width * 0.3
        rect.x, rect.y, rect.width, rect.height = 120, 0, child2_width, height
        self.child2.size_allocate(rect, baseline)
        # Third child takes 70%
        child3_width =  remaining_width - child2_width
        rect.x, rect.y, rect.width, rect.height = 120+child2_width, 0, child3_width, height
        self.child3.size_allocate(rect, baseline)

What you’re doing is not supported by GTK’s layout machinery: the size of a widget is determined by its children.

The fact that it works in GTK3 is an unintended effect of undefined behaviour.

The do_size_allocate() method is just how pygobject translates GObject virtual functions: Gtk.Widget.size_allocate

You implement size_allocate() on custom widgets, whenever they have children; you also need to implement the measure() virtual function: Gtk – 4.0: Coordinate systems in GTK

What you cannot do is overriding the size_allocate() implementation of an existing widget; that will inevitably break things. That’s one of the reasons why GTK4 removed the GtkWidget::size-allocate signal.

Hi Emmanuele. Thanks for replying. Sorry - I made a mistake in my post’s subject. I’m not trying to resize the Gtk.ColumnView - I’m trying to resize the Gtk.ColumnViewColumn. I see in the docs that this appears to be supported - ie: Gtk.ColumnViewColumn.set_fixed_width

That’s what I’m trying to set - but when the parent ( ie the Gtk.ColumnView ) is resized. I’m pretty sure this is supported?

At this point, I’ve managed to prove to myself that this indeed does work, by setting up a method that’s called in a GLib.timeout … which checks the ColumnView’s size against the last time it was run … and resizes all ColumnViewColumns if things have changed. Actually this works perfectly! But obviously the GLib.timeout is not the correct way to detect changes to the ColumnView’s size. What’s a better way to trigger this?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.