我有一个简单的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 :(得分: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;
}