Signal / Property to connect when a GtkWidget is allocated


I need to know the widget (Shumate.SimpleMap) allocated size to determine a map bounding box. This calculation is done before the window containing the widget is shown on screen.

I try to connect to several signals (map, realize, show) but the widget’s methods get_allocated_height() or get_allocated_width() always return 0.

So, what signal / property should I connect to in order for these methods to return the allocated size ? Or do I have to wait for the window to be shown on screen to perform this calculation ?

Kind regards,

There is no signal for that.

The only way to know when a widget is allocated is to write your own widget subclass; then you can override the GtkWidgetClass.size_allocate() virtual function and get the allocation size as given to you by the parent widget.


Thanks for your reply.
Can you provide a sample code to achieve your suggestion ?


Not really, because it depends on what you want to achieve, and whether or not the widget you are using allows code to derive from it.


Below are some code extracts.
I am using a Shumate.SimpleMap wich is a Gtk.Widget.

Main window containing the Shumate.SimpleMap in a Gtk.Box:

class GpxDetailedView(Adw.Window):
    """Display an interactive map and a chart to analyse a gpx file."""

    __gtype_name__ = "GpxDetailedView"

    _menu_button = Gtk.Template.Child()
    _box_container = Gtk.Template.Child()
    _points_label = Gtk.Template.Child()
    _length_label = Gtk.Template.Child()
    _up_hill_label = Gtk.Template.Child()
    _down_hill_label = Gtk.Template.Child()

    def __init__(self, path):

Shumate.SimpleMap widget:

class ShumateMap(Shumate.SimpleMap):
    """Display an interactive map.

    Contains the following elements:
        * Zoom
        * License
        * Scale
        * Compass

    def __init__(self, window):

        self._settings ="")
        self._gpx_helper = window.gpx_helper

        self._path_layer = None
        self._marker_layer = None
        self._marker = None


During the __init__(), I am calling this method (in which I need the widget allocated height and width for calculations):

    def set_center_and_zoom(self) -> None:
        """Set map center and zoom based on the path layer bounds.

        FixMe: Improve calculations if poles / 180th meridian is crossed

        @return: None
        @rtype: None

        def get_latitude_derivation(latitude):
            radians = math.radians(latitude)
            return math.asinh(math.tan(radians)) / math.pi / 2

        def get_latitude_derivation_reverse(latitude_derivation):
            radians = math.atan(math.sinh(latitude_derivation * 2 * math.pi))
            return math.degrees(radians)

        bounds = self._gpx_helper.gpx.get_bounds()

        min_latitude = bounds.min_latitude
        min_longitude = bounds.min_longitude
        max_latitude = bounds.max_latitude
        max_longitude = bounds.max_longitude

        min_latitude_derivation = get_latitude_derivation(min_latitude)
        max_latitude_derivation = get_latitude_derivation(max_latitude)
        mean_latitude_derivation = (min_latitude_derivation + max_latitude_derivation) / 2

        latitude_fraction = max_latitude_derivation - min_latitude_derivation
        longitude_fraction = (max_longitude - min_longitude) / 360

        tile_size = self.get_map_source().get_tile_size()
        map_height = 363 * 0.95  # self.get_allocated_height() | Offset
        map_width = 599 * 0.95  # self.get_allocated_width() | Offset

        max_zoom_level = self.get_map_source().get_max_zoom_level()
        latitude_zoom_level = math.log(map_height / tile_size / latitude_fraction) / math.log(2)
        longitude_zoom_level = math.log(map_width / tile_size / longitude_fraction) / math.log(2)
        zoom_level = min(max_zoom_level, latitude_zoom_level, longitude_zoom_level)

            (min_longitude + max_longitude) / 2,


You should override the size_allocate() virtual function of Gtk.Widget by adding:

def do_size_allocate(self, width: int, height: int, baseline: int) -> None:
    # Chain up
    Shumate.SimpleMap.do_size_allocate(self, width, height, baseline)
    # do something with width and height

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