GtkGlade编程详解资料.docx
《GtkGlade编程详解资料.docx》由会员分享,可在线阅读,更多相关《GtkGlade编程详解资料.docx(41页珍藏版)》请在冰豆网上搜索。
GtkGlade编程详解资料
Byyfq
Gtk+/Glade编程
(一)--简介1
Gtk+/Glade编程
(二)--入门 6
Gtk+/Glade编程(三)菜单和工具栏12
Gtk+/Glade编程(四)布局管理 19
Gtk+/Glade编程
(一)--简介
Byunanao
本文是我学习GTK+和glade3进行图形界面编程的一点学习心得的整理,主要是使用GTK+/Glade编程的文档较少,而且没有说名如何将二者联系起来,以及二者之间的关系。
本文通过比较使用Glade和不使用Glade进行GUI编程进行比较,找出二者的异同,从而可以为学习使用Glade进行GUI设计提供一点学习思路。
一、什么是GTK+
首先,GTK+并不是一门编程语言,而是一个开发工具套件,或者说是一个开发库,用来进行跨平台GUI应用程序的开发,Linux,Windows或其它平台都能使用
GTK+。
GTK+就好比Windows上的MFC和Win32API,JAVA上的Swing和SWT,或者Qt(KDE使用的Linux下GUI开发套件)。
尽管GTK+是用纯C语言编写的,但是提供了其它各种语言的捆绑,允许程序员选择自己喜欢的开发语言来开发GTK+应用程序,比如C++,Python,Perl,PHP,Ruby等等。
GTK+开发套件基于三个主要的库:
Glib,Pango和ATK,当然我们只需关心如何使用GTK+即可,GTK+自己负责与这三个库打交道。
Glib封装了大部分可移植的
C库函数(允许你的代码移植到Windows和Linux上运行)。
使用C或C++时,将大量使用Glib库函数,在我们用C语言的具体实现过程中我会详细解释它们。
高级语言如Python和Ruby却不用担心Glib的使用,因为它们有自己的标准库提供了相应的功能。
GTK+及相关的库时按照面向对象设计思想来实现的,至于这时如何实现的现在并不重要,不同的编程语言有不同的实现方法,重要的是要知道GTK+使用面向对象编程技术即可(是的,即使是C实现的)。
每一个GTK+的GUI元素都是由一个或许多个“widgets”对象构成的。
所有的widgets都从基类GtkWidget派生。
例如,应用程序的主窗口是GtkWindow类widget,窗口的工具条是GtkToolbar类widget。
一个GtkWindow是一个GtkWidget,但一个GtkWidget并不是一个GtkWindow,子类widgets继承自父类并扩展了父类的功能而成为一个新类,这就是标准的面向对象编程思想。
我们可以查阅GTK+参考手册找到widgets直接的继承关系。
对于GtkWindow它的继承链看起来像这样:
GObject
+----GInitiallyUnowned
+----GtkObject
+----GtkWidget
+----GtkContainer
+----GtkBin
+----GtkWindow
因此,GtkWindow继承自GtkBin,GtkBin继承自GtkContainer,等等。
在第一个程序中,你不需要担心GtkWidget对象。
各widget之间的继承链之所以重要是因为当你查找某个widget的函数,属性和信号时,你应该知道它的父类的函数,属性和信号也被此widget继承了,可以直接使用。
在第二部分讲述此实例的代码时,
你能更清楚的认识到这一点。
我们来看命名规则,命名规则带来的好处是非常便于使用。
我们能够清楚的看出对象或函数是哪个库中的。
以Gtk开头的所有对象都是在
GTK+中定义的。
稍后我们会看到类似GladeXML以Glade开头的是Libglade库对象或函数,GError以G开头的在GLib库定义。
所有Widgets类都遵循标准camelcase命名习惯。
所有操作函数都以下划线组合小写字母单词命名。
如gtk_window_set_title()设置GtkWindow对象的标题属性。
二、Glade
Glade是一种开发GTK+应用程序的RAD(RapidApplicationDevelopment)工具。
Glade自身就是一个GTK+应用程序,因为它就是用GTK+开发出来的,Glade
用来简化UI控件的设计和布局操作,进行快速开发。
Glade的设计初衷是把界面设计与应用程序代码相分离,界面的修改不会影响到应用程序代码,Glade设计的界面保存为glade格式文件,它实际上是一种XML文件。
Glade起先能根据创建的GUI自动生成C语言代码(你仍然能找到此类相关的实例),后来可以利用Libglade库在运行时动态创建界面,到了Glade3,这些方法都不赞成使用了。
这是因为,Glade需要做的唯一的事就是生成一个描述如何创建GUI的glade文件。
这给编程人员提供了更多的灵活性和弹性,避免了用户界面部分微小的改变就要重新编译整个应用程序,同时其语言无关性,几乎所有的编程语言都可以使用Glade。
三、Gtk+和Glade相关开发环境的搭建
以Debian为例:
安装对应的包名为:
·gtk+:
libgtk2.0-dev
·gcc:
build-essential
·glade:
glade
·make:
make
·Devhelp:
devhelp
#aptitudeinstalllibgtk2.0-devgladebuild-essentialmakedevhelp
注:
包的名字可能改变(主要是版本号的改变),如果安装的时候,说找不到哪个包,可以使用aptitudesearch包名 (如aptitudesearchgtk)
四、文档的获得
1、Gtk+Tutors:
http:
//library.gnome.org/devel/gtk-tutorial/stable/ (官方)
ftp:
/ftp.gtk.org/pub/gtk/tutorial (pdf)
初学者的tutors:
2、GtkBuilder
http:
//library.gnome.org/devel/gtk/stable/GtkBuilder.html
3、手册
“应用程序”-->"编程"-->"Devhelp"
4、更多文档:
http:
//www.gtk.org/documentation.html
四、熟悉Glade
1、启动Glade
如果有“SetOptionsinyourproject”的窗口,直接关闭即可
2、熟悉Glade的主界面
左边的是"Palette"就像是一个图形编辑程序,可以用它上面的GtkWidgets来设计你的用户界面。
中间部分(刚启动时是空白一片)是"Editor"所见即所得的编辑器。
在右边,上部是"Inspector",下部是widget"Properties"。
Inspector以树形显示当前创建的控件的布局,可以对控件进行选择。
我们通过Properties中各项内容来设置widgets的属性,包括设置widgets的信号回调函数。
五、编程实现一个简单的窗口:
点击Palette上"Toplevels"分组框中的GtkWindow图标,你会看到一个灰色窗口出现在Glade中间的Editor区域。
这是GtkWindow的工作区
窗口管理器(如GNOME)会自动加上窗口标题,关闭按钮等,因此我们编辑时看不见。
使用Glade时,我们总是需要首先创建一个顶层窗口,典型的是创建一个GtkWindow。
以"window.glade"文件名保存工程。
这个文件是一个XML文件,你可以在文本编辑器中打开它:
xmlversion="1.0"?
>
--interface-naming-policyproject-wide-->
你看,这就是一个简单的XML文件,Glade能在修改过程中自动保存到该文件。
五、编写一个简单窗口的程序
1、使用glade生成的window.glade,编写一个简单窗口的程序
/*
Thensavethisfileaswindow.candcompileitusingthiscommand
(thosearebackticks,notsinglequotes):
gcc-Wall-g-owindowwindow.c`pkg-config--cflags--libsgtk+-2.0`
Thenexecuteitusing:
./window
*/
#include
intmain(intargc,char*argv[])
{
GtkBuilder *builder;
GtkWidget *window;
gtk_init(&argc,&argv);
builder=gtk_builder_new();
gtk_builder_add_from_file(builder,"window.glade",NULL);
window=GTK_WIDGET(gtk_builder_get_object(builder,"window1"));
gtk_builder_connect_signals(builder,NULL);
g_object_unref(G_OBJECT(builder));
gtk_widget_show_all(window);
gtk_main();
return0;
}
编译:
$gcc-owindowwindow.c`pkg-config--cflags--libsgtk+-2.0`
运行:
$./window
2、不使用glade生成,而是在c代码中直接创建
#include
intmain(intargc,char*argv[])
{
GtkWidget*window;
gtk_init(&argc,&argv);
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show(window);
gtk_main();
return0;
}
总结:
比较1和2,可以发现:
使用Glade生成的xml文件进行解析生成GUI
·不需要调用gtk_window_new(直接由xml文件解析创建)
·需要调用GtkBuilder(由GtkBuilder解析xml文件)
所以可以发现使用Glade设计UI,然后用于Gtk程序中十分容易,但是要想知道各个组建如何使用,如何选择组建,还是要学习Gtk+的文档。
虽然glade可以帮我们完成界面的设计,但是只是界面而已,各个组件的用法还是要参考GTK+的tutors和手册。
下面将比较使用glade进行界面设计和使用gtk+直接编程的区别,从而理解使用gtk+/glade进行编程。
Gtk+/Glade编程
(二)--入门
本文将porgrams”一章中内容采用Glade进行界面设计的方法完成“Firstporgrams”的例子,并且增加一些解释说明。
由于“Simpleexample”已经在《Gtk+/Glade编程
(一)》中实现,这里就不再进行实现。
一、将窗口放置在屏幕中间
主要是窗口属性的设置,在右下角处的“属性”里面进行设置:
这样可以从右下角看到窗口对象的名称被设为:
“Center”,窗口的标题被设为“Center”,长度为:
230,高度:
150。
保存并且命名为"center.glade"。
代码为:
#include
intmain(intargc,char*argv[])
{
GtkBuilder*builder;
GtkWidget*window;
gtk_init(&argc,&argv);
builder=gtk_builder_new();
gtk_builder_add_from_file(builder,"center.glade",NULL);
window=GTK_WIDGET(gtk_builder_get_object(builder,"center"));
//用于关闭窗口,也可以在属性的信号中进行设置
g_signal_connect(GTK_WINDOW(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);
gtk_widget_show(window);
g_object_unref(builder);
gtk_main();
return0;
}
编译:
$gcc-ocentercenter.c`pkg-config--cflags--libsgtk+-2.0`
执行:
$./center
点击关闭按钮可以正常关闭。
如果不使用Glade进行界面设计及生成,生成窗口并且设置属性的步骤为:
#include
intmain(intargc,char*argv[])
{
GtkWidget*window;
gtk_init(&argc,&argv);
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),"center");//titleis"window"
gtk_window_set_default_size(GTK_WINDOW(window),230,150);
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
gtk_widget_show(window);
gtk_main();
return0;
}
对比可知:
创建一个组件,
使用Gtk+
·需要new一个组件
·通过set进行属性设置
使用Glade/Gtk+
·需要在点击生成窗口,
·通过属性设置栏进行属性设置
·利用GtkBuilder将生成的xml文件加入进来即可
虽然感觉Glade/Gtk+的步骤更多,但是并没有直接使用Gtk+繁琐,尤其是Glade可以设计所见即所得的界面,使得编码更加方便,更加高效!
二、应用程序的图标
只需“常规”的设置中,找到“图标”,选择需要设置为图标的图片即可,如下图:
其他的设置没有改变,Gtk+的代码与“一、将窗口放置在屏幕中间”的代码相同(如果保存的xml的名字进行了改动,需要修改Gtk+中gtk_builder_add_from_file的文件名)
运行结果截图:
左上角出现了我们加入的图标,比上面的图都是“X”漂亮多了!
^_^
三、加-减
3个子组件,1个“标签”,2个“按钮”
·“标签”-->显示一个整数
·“+”,“-”—>增加或减小标签上的数字。
首先设计界面:
在“顶层”中选“窗口”
在“容器”中选“固定的” --用于固定按钮和标签,不然加入这些组件的任何一个都会充满整个“窗口”
在控制和显示中选“按钮”和 “标签” (标签是黑色的,不带下划线的“Label”)
然后点击菜单栏最右边的“拖拽并调整工作区部件的大小”,调整“按钮”和“标签的”大小及位置。
设置各个组件的属性:
设置按钮的标签:
设置标签的属性:
最后是Gtk+编程:
unanao@debian:
~/gui/first-programs$catdec_inc.c
#include
gintcount=0;
gcharbuf[6];
voidincrease(GtkWidget*widget,GtkLabel*label)
{
count++;
sprintf(buf,"%d",count);
gtk_label_set_text(label,buf);
}
voiddecrease(GtkWidget*widget, GtkLabel*label)
{
count--;
sprintf(buf,"%d",count);
gtk_label_set_text(label,buf);
}
intmain(intargc,char*argv[])
{
GtkBuilder*builder;
GtkWidget*window;
GtkWidget*plus;
GtkWidget*minus;
GtkWidget*result;
gtk_init(&argc,&argv);
builder=gtk_builder_new();
gtk_builder_add_from_file(builder,"dec_inc.glade",NULL);
window=GTK_WIDGET(gtk_builder_get_object(builder,"window"));
plus=GTK_WIDGET(gtk_builder_get_object(builder,"plus"));
minus=GTK_WIDGET(gtk_builder_get_object(builder,"minus"));
result=GTK_WIDGET(gtk_builder_get_object(builder,"label"));
gtk_widget_show_all(window);
g_signal_connect(window,"destroy",G_CALLBACK(gtk_main_quit),NULL);
g_signal_connect(plus,"clicked",G_CALLBACK(increase),result);
g_signal_connect(minus,"clicked",G_CALLBACK(decrease),result);
gtk_main();
return0;
}
编译:
gcc-odec_incdec_inc.c`pkg-config--cflags--libsgtk+-2.0`
执行:
./dec_inc
通过点击“+”和“-”就可以改变右边数字的值了。
四、信号和回调函数
注意这里的回调函数和普通的函数不一样,虽然g_signal_connect只传了一个参数,但是回调函数是两个函数,我开始感觉这个例子写的够笨的,本来传了一个参数,回调函数居然写了两个参数,我就去掉了一个参数,结果执行结果会报错说传入的参数不是“标签”。
要使一个按钮执行一个动作,我们需设置信号和信号处理函数之间的连接。
可以这
样使用函数来设置连接:
gulongg_signal_connect(gpointer *object,
constgchar *name,
GCallback func,
gpointer func_data);
第一个参数是要发出信号的构件,第二个参数是你想要连接的信号的名称,第三个
参数是信号被捕获时所要调用的函数,第四个参数是你想传递给这个函数的数据。
第三个参数指定的函数叫做回调函数:
voidcallback_func(GtkWidget*widget,
gpointer callback_data);
第一个参数是一个指向发出信号的构件的指针,第二个参数是一个指向数据的指针
,就是g_signal_connect()函数的最后一个参数。
注意上面回调函数的声明是一种常用的形式,有些构件的特殊信号会用不同的调用
参数。
另一个调用在形式helloworld程序中使用,是:
gulongg_signal_connect_swapped(gpointer *object,
constgchar *name,
GCallback func,
gpointer *slot_object);
g_signal_connect_swapped()和g_signal_connect()相同,只是回调函数只用
一个参数,一个指向GTK对象的指针。
所以当使用这个函数连接信号时,回调函
数应该是这样的形式
voidcallback_func(GtkObject*object);
这个对象常是一个构件。
然而我们通常不用函数g_signal_connect_swapped()设
置连接。
它们常被用在只接受一个单独的构件或者对象的回调函数中作为参数,如
同