[pygtk] Apportioning space when resizing a box

John Dennis jdennis at redhat.com
Fri Mar 2 01:41:43 WST 2007

On Wed, 2007-02-28 at 20:43 -0700, Jeffrey Barish wrote:
> Is there a way to apportion space when resizing a box?  For example, suppose
> that you have two widgets in a hbox.  Is there a way to specify that one
> should get 1/3 of the available width and the other 2/3?  I'm looking for
> something like that the wxPython proportion parameter.
> Also, is there a concept of a spacer?  You might have two widgets that you
> want spaced uniformly on a line.  Specifying spacer | widget1 | spacer |
> widget2 | spacer and turning fill on for the spacers but not for the
> widgets would get the job done.  Is there another way?

I ran into the same problem recently and solved it by subclassing HBox
and overriding the size_allocate function which assigns the position and
size for its children. In the class I assign a percentage to each child
and scale the size of each child in size_allocate() by that percentage.
Here is a code snippet for the class minus the bulk of __init__() which
is just boring widget creation. HTH, John

class BrowserStatusBar(gtk.HBox):
    '''Status bar with fixed size icon on the left, followed by scaled 
    visit message, count message, status message, and progress bar.
    Each of these widget live in their own frame.'''

    # These proportions should sum to 1.0
    visit_msg_proportion    = 0.20
    alert_count_proportion  = 0.10
    status_msg_proportion   = 0.55
    progress_proportion     = 0.15

    def __init__(self):
	# Widget creation deleted for brevity
    def do_size_allocate(self, allocation):
        max_x = allocation.x + allocation.width
        child_rect = gtk.gdk.Rectangle(allocation.x, allocation.y,
                                       allocation.width, allocation.height)

        # Compute size for connection icon
        icon_width, icon_height = self.connect_icon_frame.size_request()

        # Total space available for fixed sized items
        fixed_width_total = icon_width
        fixed_width_total = min(allocation.width, fixed_width_total)
        fixed_width_remaining = fixed_width_total

        # Total space available remaining for scaled items
        scaled_width_total = allocation.width - fixed_width_total
        scaled_width_remaining = scaled_width_total

        # Move left to right laying out items:
        # [connection icon][visit msg][status msg][progress bar]

        # Connection Icon
        child_rect.width = min(fixed_width_total, icon_width)
        child_rect.x += child_rect.width
        fixed_width_remaining = fixed_width_remaining - child_rect.width

        # Visit Message
        child_rect.width = int(scaled_width_total * self.visit_msg_proportion)
        if (child_rect.x + child_rect.width) > max_x:
            child_rect.width = max_x - child_rect.x
        scaled_width_remaining = scaled_width_remaining - child_rect.width
        child_rect.x += child_rect.width

        # Alert Count
        child_rect.width = int(scaled_width_total * self.alert_count_proportion)
        if (child_rect.x + child_rect.width) > max_x:
            child_rect.width = max_x - child_rect.x
        scaled_width_remaining = scaled_width_remaining - child_rect.width
        child_rect.x += child_rect.width

        # Status Message
        child_rect.width = int(scaled_width_total * self.status_msg_proportion)
        if (child_rect.x + child_rect.width) > max_x:
            child_rect.width = max_x - child_rect.x
        scaled_width_remaining = scaled_width_remaining - child_rect.width
        child_rect.x += child_rect.width

        # Progress Bar
        # Note, we don't compute the proportionate space for the last scaled item
        # because of potential rounding errors, we just use whats left
        child_rect.width = scaled_width_remaining
        if child_rect.x + child_rect.width > max_x:
            child_rect.width = max(0, max_x - child_rect.x)

John Dennis <jdennis at redhat.com>

Learn. Network. Experience open source.
Red Hat Summit San Diego  |  May 9-11, 2007
Learn more: http://www.redhat.com/promo/summit/2007

More information about the pygtk mailing list