[pygtk] How to do_size_allocate properly in a gtk.Viewport subclass?

John Finlay finlay at moeraki.com
Thu Oct 23 06:27:12 WST 2008


Joel Hedlund wrote:
> Hi!
>
> I was directed here from comp.lang.python, so sorry for the cross-post. 
>   I've also raised this issue on #pygtk and #gtk+ but with no luck. I 
> haven't been able to solve this even with aid of google, the pygtk 
> reference and the gtk C source, so pretty please help?
>
> I'm making an application that you can think of as an image viewer. I
> want to display a widget in a gtk.Viewport. The widget can have any size
> from tiny to humungous. I don't want the viewport to ever give the
> widget a larger size allocation than requested, and I don't want the
> viewport to ever resize to accomodate a large widget. It should rather
> leave grey areas around the widget/show only a portion of the widget.
>
> To do this I have subclassed gtk.Viewport (MyViewport) and overrided the
> do_size_allocate method:
>
>   
>>     def do_size_allocate(self, allocation):
>>         self.allocation = allocation
>>         child_req = self.child.get_child_requisition()
>>         child_alloc = gtk.gdk.Rectangle(0, 0, *child_req)
>>         self.child.size_allocate(child_alloc)
>>         self.props.hadjustment.update(allocation.width, child_alloc.width)
>>         self.props.vadjustment.update(allocation.height, child_alloc.height)
>>         if self.flags() & gtk.REALIZED:
>>             self.window.move_resize(*self.allocation)
>>             self.child.window()
>>     
>
> When I add a very large widget (a gtk.DrawingArea) to MyViewport only
> the originally visible portion of the widget is redrawn when I resize
> the window using the mouse, and the grey area around widget gets
> littered with grey lines that are not redrawn if you minimize and
> restore the window. I assume this comes from that the proper gdk windows
> haven't been updated, and that the grey lines are remnants of old
> Viewport borders.
>
> In gtk_viewport_size_allocate in gtkviewport.c, gdk_window_move_resize
> is called on three gdk windows: viewport->window, viewport->view_window
> and viewport->bin_window, but in pygtk I only have gtk.Viewport.window.
> I assume that this is the problem? If so, how can I fix this? Or is
> there something else that I have overlooked?
>
> And another relevant question: am I overcomplicating this? Is there some
> kind of flag that I could set on a vanilla viewport to accomplish this?
>   
I'm not sure what behavior you are looking for so I'll assume that you 
have one widget (e.g. Image) that you want to put inside a Viewport in a 
ScrolledWindow in a Window. I'll also assume that you want the widget to 
float in the center of the Window when the widget is smaller than the 
Window. Finally I assume that you want the widget to be partially 
displayed but scrollable within the window when the widget is larger 
than the Window. If these assumptions are wrong that ignore the 
following suggestion.

If so then I suggest that you put the widget inside a Table of size 1,1 
and attach it with EXPAND but not FILL. Put the table in a Viewport 
inside a ScrolledWindow inside a Window. This should keep the widget to 
a fixed size within the Window.

John


More information about the pygtk mailing list