搞Gtk的大牛们搞什么飞机哦,布局Widget这样的东西,居然被大牛们当成MM一样藏起来拉!就藏在GIMP里面作Custom Widget也不放到GTK作为标准控件。
做一个小玩意时我遇到了一个比较令人苦恼的问题,那就是Gtk+ 的布局管理Widget里面没有那种像Java Flowlayout一样的东西。什么box,什么frame,都不是我想要的。
记得学java布局管理的时候觉得流式布局真白痴,其实也有可用之处啊,最典型的就是GIMP和Dia这样的toolbox啦,就像下面这样,在WIndows的UI系统里面搞这个不是那么容易的吧…

Dia toolbox
我在Gtk的参考里面找啊找,还是没找到,于是去看Dia的源代码去。
NNNNND!我我居然发现了一个叫GtkWrapBox的Widget。NNND,去google一看,还真有这个玩意,就在Gimp的在线Gtk接口文档中。
可以看到这个叫GtkWrapBox的Widget有两个派生,分别是横向折行和纵向折行;可以看到这个叫GtkWrapBox的Widget还是GtkContainer的派生类;但是最可恶的地方就是——你去看文档里面的Object Hierarchy吧,GtkContainer下绝对没有GtkWrapBox,GtkWrapBox的上层Object绝对是 GtkContainer。NND。
http://developer.gimp.org/api/2.0/app/GtkWrapBox.html#id3166842
http://developer.gimp.org/api/2.0/gtk/GtkContainer.html#id3824858
搞Gtk的大牛们搞什么飞机哦,布局Widget这样的东西,居然被大牛们当成MM一样藏起来拉!就藏在GIMP里面作Custom Widget也不放到GTK作为标准控件。
好了,既然这样就好办了。我去把GtkWrapBox的源码搞过来看一下就好了。源码如下:
$ ls *.c *.h
gtkhwrapbox.c gtkvwrapbox.c gtkwrapbox.c
gtkhwrapbox.h gtkvwrapbox.h gtkwrapbox.h
下面我来测试一下下啦。我拿GTK 的Hello World改了一段代码,可用!
[main.c]:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #include <gtk/gtk.h> #include <gtk/gtk.h> #include <gtk/gtkcontainer.h> #include "gtkhwrapbox.h" /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ static void hello( GtkWidget *widget, gpointer data ) { g_print ("Hello World\n"); } static gboolean delete_event( GtkWidget *widget, GdkEvent *event, gpointer data ) { /* If you return FALSE in the "delete_event" signal handler, * GTK will emit the "destroy" signal. Returning TRUE means * you don't want the window to be destroyed. * This is useful for popping up 'are you sure you want to quit?' * type dialogs. */ g_print ("delete event occurred\n"); /* Change TRUE to FALSE and the main window will be destroyed with * a "delete_event". */ return TRUE; } /* Another callback */ static void destroy( GtkWidget *widget, gpointer data ) { gtk_main_quit (); } int main( int argc, char *argv[] ) { /* GtkWidget is the storage type for widgets */ GtkWidget *window; GtkWidget *button[10]; /* This is called in all GTK applications. Arguments are parsed * from the command line and are returned to the application. */ gtk_init (&argc, &argv); /* create a new window */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); //给windows连接delete_event信号 g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (delete_event), NULL); //给windows连接destroy信号 g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL); //设置边框 gtk_container_set_border_width (GTK_CONTAINER (window), 10); // 创建一个 hwrapbox GtkWidget * wrapbox = gtk_hwrap_box_new(FALSE); /* 创建 10 个 button with the label "Fuck Off". */ int i = 0; for (i = 0; i < 10; ++i) { button[i] = gtk_button_new_with_label ("Fuck Off"); //将clicked信号连接到hello函数 g_signal_connect (G_OBJECT (button[i]), "clicked", G_CALLBACK (hello), NULL); //将clicked信号连接到gtk_widget_destroy, 考虑到该 //函数接受一个widget参数, So, 使用g_signal_connect_swapped g_signal_connect_swapped (G_OBJECT (button[i]), "clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT (window)); //将各个button打包进wrapbox gtk_wrap_box_pack(GTK_WRAP_BOX(wrapbox), button[i], FALSE, FALSE, FALSE, FALSE); //显示各个button gtk_widget_show (button[i]); } //把wrapbox加入window gtk_container_add (GTK_CONTAINER (window), wrapbox); // 显示wrapbox和windows. gtk_widget_show (wrapbox); gtk_widget_show (window); //gtk main入口函数 gtk_main (); return 0; } |
这里是我用的makefile:
[makefile]:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | GLADE_ADD = -export-dynamic -Wall LINKFLAGS = `pkg-config --libs gtk+-2.0 libglade-2.0` $(GLADE_ADD) CFLAGS = `pkg-config --cflags gtk+-2.0 libglade-2.0` $(GLADE_ADD) OBJ = main.o gtkhwrapbox.o gtkvwrapbox.o gtkwrapbox.o main: $(OBJ) gcc -o main $(OBJ) $(LINKFLAGS) %.o: %.c gcc -g -c $(CFLAGS) $< -o $@ clean: rm -f *.o main |
下面是screenshot, 还是可以的啦 , 不过嗯个,还有个问题,因为这个玩意不属于gtk标准组件,所以pygtk里面也没有它啦,那…岂不是要我自己搞一下 (ToT)。
Tags: flowlayout, gtk, layout, linux, programming, 布局, 流式布局


