2016-11-17 114 views
0

我有一个简单的GTK3应用程序,它显示窗口中文件的图像。 调整窗口大小时,图像在展开回调中缩放以适应窗口。如何制作GTK3图像窗口缩小图像?

但是,一旦窗口增大,就不能缩小它;调整大小手柄只能让你使窗口更大。

在GTK2中,通过gtk_window_set_policy(w,1,1,1)可以进行增长和缩小是微不足道的。

如何在GTK3中实现相同的效果?

这里的日益增长的代码示例:

#include <gtk/gtk.h> 
#include <gdk-pixbuf/gdk-pixbuf.h> 

gboolean resize_image(GtkWidget *widget, GdkEvent *event, void *data) 
{ 
    GdkPixbuf *pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(widget)); 
    if (pixbuf == NULL) 
    { 
     g_printerr("Failed to get pixbuf\n"); 
     return 1; 
    } 

    pixbuf = gdk_pixbuf_scale_simple(pixbuf, 
      widget->allocation.width, widget->allocation.height, 
      GDK_INTERP_BILINEAR); 

    gtk_image_set_from_pixbuf(GTK_IMAGE(widget), pixbuf); 

    return FALSE; 
} 

int main(int argc, char **argv) 
{ 
    GtkWidget *window = NULL; 
    GtkWidget *image = NULL; 

    if (argc < 2 || argc > 3) 
    { 
     g_printerr("Usage: %s <image>\n", argv[0]); 
     return 1; 
    } 

    gtk_init(&argc, &argv); 

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    image = gtk_image_new_from_file(argv[1]); 
    if (image == NULL) 
    { 
     g_printerr("Could not open \"%s\"\n", argv[1]); 
     return 1; 
    } 

    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); 
    g_signal_connect(image, "expose-event", G_CALLBACK(resize_image), NULL); 

    gtk_container_add(GTK_CONTAINER(window), image); 
    gtk_widget_show_all(GTK_WIDGET(window)); 

    gtk_main(); 

    return 0; 
} 
+0

我觉得'argc!= 2'比您的表情更容易阅读 –

+1

诀窍是在它周围使用'GtkScrolledWindow'并将图像大小调整为'GtkImage'的大小。这是什么对我来说适用于Python :) – B8vrede

+0

非常感谢您的建议。它有点类似于作品,但滚动条不断弹出并消失,当图像被调整大小时,图像会抖动,有时会留下正确的窗口大小,但显示的滚动条显示图像居中更大的白色帆布在两个方向上都有数十个更大的圆点。这似乎是GTK3能做的最好的! – martinwguy

回答

0

埃里克Cecashon GTK的列表邮件列表上建议使用开罗绘制一个1x1的网格容器内区域,其工作相当好:

/* 
    gcc -Wall da_resize.c -o da_resize `pkg-config gtk+-3.0 --cflags --libs` 
    Tested on Ubuntu16.04, GTK3.18. 
*/ 

#include<gtk/gtk.h> 

gboolean draw_picture(GtkWidget *da, cairo_t *cr, gpointer data) 
{ 
    gint width=gtk_widget_get_allocated_width(da); 
    gint height=gtk_widget_get_allocated_height(da); 

    GdkPixbuf *temp=gdk_pixbuf_scale_simple((GdkPixbuf*)data, width, height, GDK_INTERP_BILINEAR); 
    gdk_cairo_set_source_pixbuf(cr, temp, 0, 0); 
    cairo_paint(cr); 

    g_object_unref(temp); 
    return FALSE; 
} 
int main(int argc, char *argv[]) 
{ 
    gtk_init(&argc, &argv); 

    GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    gtk_window_set_title(GTK_WINDOW(window), "Resize Picture"); 
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); 
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 400); 

    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); 

    //Needs a valid picture. 
    GdkPixbuf *pixbuf=gdk_pixbuf_new_from_file(argc>1 ? argv[1] : "image.jpg", NULL); 

    GtkWidget *da1=gtk_drawing_area_new(); 
    gtk_widget_set_hexpand(da1, TRUE); 
    gtk_widget_set_vexpand(da1, TRUE); 
    g_signal_connect(da1, "draw", G_CALLBACK(draw_picture), pixbuf); 

    GtkWidget *grid=gtk_grid_new(); 
    gtk_grid_attach(GTK_GRID(grid), da1, 0, 0, 1, 1); 

    gtk_container_add(GTK_CONTAINER(window), grid); 
    gtk_widget_show_all(window); 

    gtk_main(); 

    g_object_unref(pixbuf); 

    return 0; 
} 
+0

谢谢,但我仍然对一个必须跳过的篮球感到震惊! – martinwguy