I have a GtkImage
widget in a resizable window and a reference GdkPixBuf
storing the image I want to fill the GtkImage
with.
I can scale the GdkPixBuf
to fill the GtkImage
widget using this method:
def update_image(self, widget=None, data=None):
# Get the size of the source pixmap
src_width, src_height = self.current_image.get_width(), self.current_image.get_height()
# Get the size of the widget area
widget = self.builder.get_object('image')
allocation = widget.get_allocation()
dst_width, dst_height = allocation.width, allocation.height
# Scale preserving ratio
scale = min(float(dst_width)/src_width, float(dst_height)/src_height)
new_width = int(scale*src_width)
new_height = int(scale*src_height)
pixbuf = self.current_image.scale_simple(new_width, new_height, gtk.gdk.INTERP_BILINEAR)
# Put the generated pixbuf in the GtkImage widget
widget.set_from_pixbuf(pixbuf)
When I call update_image
manually it works as expected. Now I want the scaling to occur automatically when the GtkImage widget is resized. The best solution I came with was to bind the update_image
method to the configure-event
GTK event of the window. After each size change of the window, the image is indeed properly scaled. However I have two issues with this solution:
- I can only make the window bigger. Once the image has been upscaled, GTK won't let me resize the window smaller because the window can't be smaller than its widgets. I understand why it works like that but I don't know how to change this behaviour.
- Maybe this is no big deal but I would have preferred an event from the GtkImage widget instead of the top-level window.
I am sorry for the long explanation of such a trivial problem, I hope you'll be able to help me.
I believe you could use expose-event signal of the widget for image scaling. Also adding image into scrollable container should fix the problem with window resize. Please check if an example below would work for you.
hope this helps, regards
If you don't want to use a
GtkScrolledWindow
, you can replace yourGtkImage
with aGtkDrawingArea
instead, and then draw your image using Cairo. This will allow the images to shrink, becauseGtkDrawingArea
does not set a size request.I don't know about Python, but here is an example in C using GTK3:
If the drawing area's background appears opaque, set
gtk_widget_set_has_window ()
toFALSE
, though it's probably better to derive your own widget fromGtkDrawingArea
and set this property in itsinit
function.If you're using GTK2, the code is similar, except that you have to call
gdk_cairo_create ()
onwidget->window
and callcairo_destroy ()
when you're finished.Also, with GTK2, if the
GtkDrawingArea
doesn't have its ownGdkWindow
, the coordinates for drawing are relative to the parentGdkWindow
rather than the widget.All widgets have
size-allocate
signal.Perhaps you can use that.