如何使GTK3窗口中的图像可收缩?

时间:2016-11-17 00:59:07

标签: c 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;
}

1 个答案:

答案 0 :(得分:0)

在gtk-list邮件列表上的Eric Cecashon建议在1x1网格容器中使用cairo绘图区域,这非常有效:

/*
    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;
}