正在加载...

在Gtk+中使用流式布局

搞Gtk的大牛们搞什么飞机哦,布局Widget这样的东西,居然被大牛们当成MM一样藏起来拉!就藏在GIMP里面作Custom Widget也不放到GTK作为标准控件。

做一个小玩意时我遇到了一个比较令人苦恼的问题,那就是Gtk+ 的布局管理Widget里面没有那种像Java Flowlayout一样的东西。什么box,什么frame,都不是我想要的。

记得学java布局管理的时候觉得流式布局真白痴,其实也有可用之处啊,最典型的就是GIMP和Dia这样的toolbox啦,就像下面这样,在WIndows的UI系统里面搞这个不是那么容易的吧… :D

Dia

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) $&lt; -o $@
 
clean:
rm -f *.o main

下面是screenshot, 还是可以的啦 ,  不过嗯个,还有个问题,因为这个玩意不属于gtk标准组件,所以pygtk里面也没有它啦,那…岂不是要我自己搞一下 (ToT)。

宽度变化

宽度变化

宽度未变化

宽度未变化

喜欢这篇文章?点下面的按钮分享到:Google/豆瓣/鲜果/校内/饭否...
  • Google
  • douban
  • xianguo
  • xiaonei
  • fanfou
  • Facebook
  • del.icio.us
  • Technorati
  • Digg
  • Slashdot
  • TwitThis
  • Live
Tags: , , , , , ,

Related posts(相关文章)

19 Responses to “在Gtk+中使用流式布局”

  1. TualatriX Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    哇!这么好的文章。现在才看到,Feedsky真的出问题了!

    [Reply(回复)]

  2. shellex Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    [quote comment="216"]哇!这么好的文章。现在才看到,Feedsky真的出问题了![/quote]
    呵呵,这不是TX同学嘛。过奖过奖。你的到来让我的小博蓬荜生辉哈。

    [Reply(回复)]

  3. TualatriX Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    -_-#

    “蓬荜生辉”。。。这么夸张~那我每天都来逛了!

    另外,我在想,GTK+-3.0估计会引入很多GIMP里的东西,比如你这篇文章中写的。
    GIMP的大牛们喜欢把好东西藏着偷偷用,呵呵!

    [Reply(回复)]

  4. shellex Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    [quote comment="218"]-_-#

    “蓬荜生辉”。。。这么夸张~那我每天都来逛了!

    另外,我在想,GTK+-3.0估计会引入很多GIMP里的东西,比如你这篇文章中写的。
    GIMP的大牛们喜欢把好东西藏着偷偷用,呵呵![/quote]

    我在想移植工作会不会很难…呵呵。gtk 3确实令人期待

    [Reply(回复)]

  5. 山猫 Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    GtkWrapbox.py
    可以看这里 http://paste.ubuntu.org.cn/8327

    [Reply(回复)]

  6. shellex Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    a[quote comment="224"]GtkWrapbox.py
    可以看这里 http://paste.ubuntu.org.cn/8327/quote
    啊,非常感谢。
    :)

    [Reply(回复)]

  7. TualatriX Using Safari Safari 525.20.1 on Mac OS Mac OS X Says:

    山猫给的东西真好!
    Python版的是继承于gtk.Table的啊,好好去研究一下。

    [Reply(回复)]

  8. shellex Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    [quote comment="228"]山猫给的东西真好!
    Python版的是继承于gtk.Table的啊,好好去研究一下。[/quote]
    山猫具体是谁哈?

    这个pyGtkWrapBox基本满足需求

    [Reply(回复)]

  9. 山猫 Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    [quote comment="228"]Python版的是继承于gtk.Table的啊,好好去研究一下。[/quote]
    嗯,这个就是用来弄类似 gimp 工具面板按钮的。

    猫猫和 TualatriX
    有空也来改进下 glade2py 吧
    http://paste.ubuntu.org.cn/8340
    从 glade-3 xml 文件生成 pyGtk 代码

    我添加了 gtk.HandleBox 支持,
    不过还缺
    gtk.Toolbar

    gtk.ToolbarSpaceStyle
    gtk.ToolButton
    gtk.ToolbarChildType
    gtk.ToolbarStyle
    gtk.ToolItem

    [Reply(回复)]

  10. 山猫 Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    PyGtk 里还有个更懒的邪恶方式做流式布局,
    用 gtk.TextView 或 gtkhtml2 做容器,
    将控件插进去,
    由 gtk.TextView 或 gtkhtml2 来处理布局。

    这个 GtkLinkTextView 插按钮或文字链接比 TextView 要方便些
    http://paste.ubuntu.org.cn/8369

    [Reply(回复)]

  11. 山猫 Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    对了,猫猫 加个新评论邮件通知插件吧

    [Reply(回复)]

  12. TualatriX Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    呜~能碰到一块做Pygtk的朋友真是好难得啊。

    山猫一般都在哪里泡坛子?怎么ShelleX叫猫猫?呵呵!

    [Reply(回复)]

  13. shellex Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    [quote comment="237"]呜~能碰到一块做Pygtk的朋友真是好难得啊。

    山猫一般都在哪里泡坛子?怎么ShelleX叫猫猫?呵呵![/quote]
    他在Ubuntu中文论坛咯。因为我的头像是一只猫咪。所以叫我猫猫。

    [Reply(回复)]

  14. shellex Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    [quote comment="236"]对了,猫猫 加个新评论邮件通知插件吧[/quote]
    好像没有效果ye。我的py和gtk都是初学的说。

    [Reply(回复)]

  15. 山猫 Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    [quote comment="240"][quote comment="236"]对了,猫猫 加个新评论邮件通知插件吧[/quote]
    好像没有效果ye。我的py和gtk都是初学的说。[/quote] 需要配置 sendmail 或 smtp,
    选 sendmail 的话,可以用 msmtp-mta 之类

    [Reply(回复)]

  16. shellex Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    [quote comment="247"][quote comment="240"][quote comment="236"]对了,猫猫 加个新评论邮件通知插件吧[/quote]
    好像没有效果ye。我的py和gtk都是初学的说。[/quote] 需要配置 sendmail 或 smtp,
    选 sendmail 的话,可以用 msmtp-mta 之类[/quote]

    已经搞定了,:)
    这个是sendmail,Linux主机的说

    [Reply(回复)]

  17. 山猫 Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    [quote comment="248"]已经搞定了,:)
    这个是sendmail,Linux主机的说[/quote]

    赞,虽然邮件标题有些乱码

    [quote]date Wed, Jul 23, 2008 at 1:36 PM
    subject [ShelleX is Not ShelleXtend] New Comment On: 在Gtk+���使用流式布局[/quote]

    对了, msmtp-mta 是一个利用其他 smtp 账号发信的 sendmail, 而不是 “ms 的 mta” :)

    [Reply(回复)]

  18. shellex Using Mozilla Firefox Mozilla Firefox 3.0.1 on Linux Linux Says:

    [quote comment="251"][quote comment="248"]已经搞定了,:)
    这个是sendmail,Linux主机的说[/quote]

    赞,虽然邮件标题有些乱码

    [quote]date Wed, Jul 23, 2008 at 1:36 PM
    subject [ShelleX is Not ShelleXtend] New Comment On: 在Gtk+���使用流式布局[/quote]

    对了, msmtp-mta 是一个利用其他 smtp 账号发信的 sendmail, 而不是 “ms 的 mta” :)[/quote]
    哦,,,,这样子哈,知道了。谢谢

    [Reply(回复)]

  19. dustman Using Mozilla Firefox Mozilla Firefox 3.0.3 on Ubuntu Linux Ubuntu Linux Says:

    你也成大牛了阿

    [Reply(回复)]

来个评论吧: