Automatic image scaling on resize with (Py)GTK

穿精又带淫゛_ 提交于 2019-12-05 08:01:14

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.

import gtk

class ScaleImage:
    def __init__(self):
        self.temp_height = 0
        self.temp_width = 0

        window = gtk.Window(gtk.WINDOW_TOPLEVEL)

        image = gtk.Image()
        image.set_from_file('/home/my_test_image.jpg')
        self.pixbuf = image.get_pixbuf()
        image.connect('expose-event', self.on_image_resize, window)    

        box = gtk.ScrolledWindow()
        box.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        box.add(image)

        window.add(box)
        window.set_size_request(300, 300)
        window.show_all()        

    def on_image_resize(self, widget, event, window):
        allocation = widget.get_allocation()
        if self.temp_height != allocation.height or self.temp_width != allocation.width:
            self.temp_height = allocation.height
            self.temp_width = allocation.width
            pixbuf = self.pixbuf.scale_simple(allocation.width, allocation.height, gtk.gdk.INTERP_BILINEAR)
            widget.set_from_pixbuf(pixbuf)

    def close_application(self, widget, event, data=None):
        gtk.main_quit()
        return False

if __name__ == "__main__":
    ScaleImage()
    gtk.main()

hope this helps, regards

All widgets have size-allocate signal.

The "size-allocate" signal is emitted when widget is given a new space allocation.

Perhaps you can use that.

If you don't want to use a GtkScrolledWindow, you can replace your GtkImage with a GtkDrawingArea instead, and then draw your image using Cairo. This will allow the images to shrink, because GtkDrawingArea does not set a size request.

I don't know about Python, but here is an example in C using GTK3:

gboolean drawing_area_draw (GtkWidget *widget, cairo_t *cr, GdkPixbuf *current_image)
{

    .....   //Calculate size

    pixbuf = gdk_pixbuf_scale_simple (current_image,
                                    new_width,
                                    new_height,
                                    GDK_INTERP_BILINEAR);

    gdk_cairo_set_source_pixbuf (cr, 
                                pixbuf,
                                allocation.width/2 - new_width/2, 
                                allocation.height/2 - new_height/2);
    cairo_paint (cr);

    return FALSE;
}

int main (int argc, char *argv[])
{
    .....

    drawing_area = gtk_drawing_area_new ();
    g_signal_connect (G_OBJECT (drawing_area), "draw",
            G_CALLBACK (drawing_area_draw), current_image);

    .....
}

If the drawing area's background appears opaque, set gtk_widget_set_has_window () to FALSE, though it's probably better to derive your own widget from GtkDrawingArea and set this property in its init function.

If you're using GTK2, the code is similar, except that you have to call gdk_cairo_create () on widget->window and call cairo_destroy () when you're finished.

Also, with GTK2, if the GtkDrawingArea doesn't have its own GdkWindow, the coordinates for drawing are relative to the parent GdkWindow rather than the widget.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!