大家一起用gtk编程.docx
- 文档编号:5363821
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:19
- 大小:32.75KB
大家一起用gtk编程.docx
《大家一起用gtk编程.docx》由会员分享,可在线阅读,更多相关《大家一起用gtk编程.docx(19页珍藏版)》请在冰豆网上搜索。
大家一起用gtk编程
大家一起用gtk编程1(开始与热身)
∙写在最前面
笔者写做本文的目的,主要是为初学GTK编程的新手们提供一个能够快速上手的学习档案,能够通过自己将所有的代码输入并编译,以达到学习的目的。
同时,也希望它成为一个参考手册,希望GTK中的每一个API都能在本文中找到相应的示例。
笔者将尽力保证所有的代码都是最短小的,这样才能保证大家都有足够的动力去手工输入它。
由于笔者时间及精力有限,不能一次将所有内容呈现给所有读者,因此拟定了一个计划:
每天更新一个章节的内容,在笔者的Blog上进行连载,同时会不断地对以前的内容进行修改和完善,因此为了保证大家能够读到最新的内容,请随时关注笔者的Blog:
∙为什么是GTK?
为什么不是GTK?
笔者不想花费太多的口水去辨证为什么选择GTK而不是其它的东西;任何技术都没有好坏之分,只有使用它的人有能力的强弱之别;笔者认为比较明智的做法是:
多编些程序,少做些争论。
∙1、GTK简介
GTK(GIMPToolkit)是一套用于创建图形用户界面的工具包。
它遵循LGPL许可证,所以可以用它来开发开源软件、自由软件,甚至是封闭源代码的商业软件,而不用花费任何费用来购买许可证和使用权。
当前,GTK已经被成功地应用到了大量的自由软件及商业软件中,已经取得了很大的成功。
GTK的创建者:
PeterMattis:
petm@xcf.berkeley.edu
SpencerKimball:
spencer@xcf.berkeley.edu
JoshMacDonald:
jmacd@xcf.berkeley.edu
当前,GTK主要由几大组件构成:
*Gtk+:
GTK的主要构件,包括所有的图形控件及大量实用的API。
*Glib:
包含一些标准函数的替代函数,以及一些处理链表等数据结构的函数等。
这些替代函数被用来增强GTK的可移植性,同时提供libc的对应函数的增强版本。
*Pango:
该组件用来处理国际化文字输出。
∙2、预备
工欲xxx,必先利其器!
在进行实际的程序设计之前,应该先明确一些主要的开发工具。
1)GTK是跨平台的,它能够运行于Linux/Unix/Windows/MacOS及嵌入式系统,但这不是本文所关注的重点;实际上,只要按照GTK所提供的API去编程,基本上在一个平台上设计的程序,在其它平台可以不加任何修改而成功地进行编译。
笔者使用的操作系统是:
Dubuntu-6.06,本文中所有的示例代码将在该平台上进行开发并编译运行;当然,这并不代表不能使用其它操作系统,只要安装了GCC编译环境、GTK/Glib/Libc开发库,基本上就能成功地编译运行本文中的所有示例,现就UbuntuDapper发行版GTK开发环境安装方法简述如下:
sudoapt-getinstallvim #是的,笔者使用vim来编写代码,当然您可以使用任何自己喜欢的编辑器
sudoapt-getinstallbuild-essential #这将安装
sudogcc/g++/gdb/make等基本编程工具
sudoapt-getinstallgnome-core-devel #这将安装libgtk2.0-devlibglib2.0-dev等开发相关的库文件
sudoapt-getinstallpkg-config #用于在编译GTK程序时自动找出头文件及库文件位置
sudoapt-getinstalldevhelp #这将安装devhelpGTK文档查看程序
sudoapt-getinstalllibglib2.0-doclibgtk2.0-doc
#这将安装gtk/glib的API参考手册及其它帮助文档
sudoapt-getinstalgladelibglade2-dev#这将安装基于GTK的界面构造程序
当然,其它的Linux发行版可参考相应的文档进行开发环境的搭建,各大Linux论坛是个不错的咨询地:
www.linuxsir.org,www.linuxfans.org
如果有热心的同仁能提供其它操作系统GTK开发库的安装方法,欢迎提供给我笔者,笔者将在这里分享给大家!
先行谢过了。
∙3、Hello,Dubuntu!
嗯,早就急不可待了,让我们开始我们的第一个程序吧!
本程序的主要功能:
显示一个窗口,并在窗口的标题栏显示字符串"Hello,Dubuntu!
"
源代码如下所示,编译成功后,可以通过命令行输入./hello_dubuntu来运行此程序,显示效果如下:
hello_dubuntu.c
#include
/*一般可以在/usr/include/gtk-2.0下找到上边的头文件
*上边的头文件的作用是包含进行GTK编程所有可能用到的头
*文件,包括glib.h等 */
int
main(intargc,char*argv[])
{
GtkWidget*window;
//GtkWidget是绝大部分可视组件的的基类
gtk_init(&argc,&argv);
//对程序传入的命令行参数进行标准化处理
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
//创建窗口(200x200大小)
gtk_window_set_title(GTK_WINDOW(window),"Hello,Dubuntu!
");
//设置窗口标题
gtk_widget_show(window);
//显示窗口
gtk_main();
//Gtk程序主循环
return0;
}
编译程序:
gcchello_dubuntu.c-ohello_dubuntu`pkg-config--cflags--libsgtk+-2.0` #注意:
"`"不是普通的单引号"'",而是同"~"在一起的那个符号!
是的,上边的程序非常简单,除了注释就没几条语句了!
但它确实是一个GTK程序,虽然它还不够完善,缺少信号处理,因此当您单击“关闭”按钮关闭此窗口后,实际上程序还在运行。
1)编译程序的命令行:
如上,使用GNUC语言编译器gcc,其中pkg-config--cflags--libsgtk+-2.0用于生成gcc编译及链接程序时所必须的头文件及库文件列表,在笔者的机器上运行该命令得到的结果如下:
命令:
pkg-config--cflags--libsgtk+-2.0
输出:
-I/usr/include/gtk-2.0-I/usr/lib/gtk-2.0/include-I/usr/include/atk-1.0-I/usr/include/cairo-I/usr/include/pango-1.0-I/usr/include/glib-2.0-I/usr/lib/glib-2.0/include -lgtk-x11-2.0-lgdk-x11-2.0-latk-1.0-lgdk_pixbuf-2.0-lm-lpangocairo-1.0-lfontconfig-lXext-lXrender-lXinerama-lXi-lXrandr-lXcursor-lXfixes-lpango-1.0-lcairo-lX11-lgobject-2.0-lgmodule-2.0-ldl-lglib-2.0
2)大家如果对某个GTK标准API定义,或者某个类型/常量定义不清楚,可以在devhelp帮助程序中进行搜索,以查看某参数说明。
3)gtk_init(&argc,&argv)函数用于对传入进来的标准命令行参数进行解析并处理,这些标准命令行参数为(即:
运行我们的程序时,通过命令行传入的下列参数会被自动处理):
∙--gtk-module
∙--g-fatal-warnings
∙--gtk-debug
∙--gtk-no-debug
∙--gdk-debug
∙--gdk-no-debug
∙--display
∙--sync
∙--name
∙--class
4)gtk_widget_show(window)用于告诉程序,我们的window构件已经准备完成,可以显示了。
5)gtk_main(),程序将会运行到此,然后等待“事件”的发生;当有事件发生后,将调用此事件对应的回调函数,当回调函数执行完毕,又会重新回到gtk_main(),等待新的“事件”发生。
6)宏GTK_WINDOW(window)是用于进行类型检查及转换,它将把一个可以转化为GtkWindow的构件强制转换为GtkWindow类型后传递给函数。
好了,hello_dubuntu.c理解了吗?
什么!
没有理解!
不要紧,我们下边还会有很多这样的小例子,再多输入几个就会理解了,相信我!
下集预告:
将在窗口中添加一个按钮,并为按钮关联"clicked"事件,以使单击按钮后会有一些返回。
大家一起用gtk编程2(添加按钮和连接事件)
∙4、加入按钮和事件处理函数
上回说道,咱们使用GTK创建了一个最简单的GTK程序,简单到只能显示一个200x200点大小的空白窗口,并在标题栏显示“Hello,Dubuntu!
”的字样!
虽然简单,但确实是个不错的开端,好了,咱们现在在窗口中添加一个按钮。
运行效果:
代码:
hello_dubuntu2.c
/*本例的主要目的是在窗口中显示一个按钮,
*并且单击按钮退出程序
*/
#include
void
cb_button(GtkWidget*widget,gpointerdata)
{//按钮"button"的回调函数
gtk_main_quit();
}
int
main(intargc,char*argv[])
{
GtkWidget*main_window;//主窗口对象
GtkWidget*button; //将要放置到主窗口中的按钮对象
gtk_init(&argc,&argv);
main_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(main_window),"Hello,Dubuntu2!
");
//设置窗口的默认大小(宽200,高度50)
gtk_window_set_default_size(GTK_WINDOW(main_window),200,50);
button=gtk_button_new_with_label("退出程序");
gtk_container_add(GTK_CONTAINER(main_window),button);
//为"button"连接“单击事件”要调用的回调函数
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(cb_button),NULL);
gtk_widget_show(button);
gtk_widget_show(main_window);
//上边的两句可以合为gtk_widget_show_all(window)
gtk_main();
return0;
}
编译:
gcc-ohello_dubuntu2 hello_dubuntu2.c `pkg-config--cflags--libsgtk+-2.0`
程序注释:
1)在GTK中,默认添加到窗口中的控件会自动占满所有的空间,因此当我们的程序运行时,将窗口放大时按钮也跟着放大了;这点同Windows及Qt是不相同的。
正因为如此,在GTK控件库中有几个控件专门用来进行窗口布局,比如说vbox,hbox,table,GtkPixed等,通过对它们的灵活操作,可以得到一个非常漂亮的应用程序界面!
这将在以后进行详细介绍。
2)关于事件与回调函数
事件:
GTK同许多其它的图形编程库相似,都采用事件驱动方式来工作,这就关系到出现什么事件做什么工作的问题。
(在GTK中还有个“信号”的概念,同“事件”的概念不容易分清楚,特别是刚开始学习时,不过没关系,初期我们就把它们当一个概念来理解),在GTK2.0中,一般使用g_signal_connect()函数来注册每个对象和其对应的处理函数,如本例所示。
回调函数:
实际上就是一个普通的函数,不过它并不会被显示地直接调用,而是把它的地址注册到另一个函数,在那个函数中间接地对它进行调用,这也是回调的由来。
3)在本例中,我们通过下列语句为“button”注册了一个"clicked"事件的回调函数“cb_button",前缀”cb“即”callback(回调)”的意思。
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(cb_button),NULL);
由于注册了上边的回调函数,因此当我们用鼠标单击按钮时,就会激发按钮的“clicked”事件,因此会调用cb_button()函数,而此函数中的语句 gtk_main_quit()的作用是退出程序,因此我们单击按钮后整个程序就会退出。
4)当然,这个程序还有个小“bug”,即直接单击右上角的“关闭按钮”关闭程序后,虽然主窗口消失了,但程序并没有直接地退出,还驻留在内存中。
这是因为当单击右上角的“关闭按钮”关闭程序后,会产生“destroy”信号,而我们并没有为此信号使用g_signal_connect()函数注册相关的处理函数,因此它的行为并不是我们所期望的;解决方法就是为主窗口的”destroy"信号注册一个回调函数,并在此回调函数中调用gtk_main_quit()以便退出程序,将如下代码添加到hello_dubuntu2.c的gtk_main()函数调用的上边就行:
g_signal_connect(G_OBJECT(main_window),"destroy",G_CALLBACK(cb_button),NULL);
请注意:
在这里我们再一次使用了"cb_button“函数,这是因为它的行为正是我们想要的,即”调用此回调函数后,退出程序“。
好了,今天的内容差不多了,很多内容都没有深入研究,不过没关系,慢慢来,以后将要以专题的形式对GTK的每个部件及API进行深入并细致的说明。
如果您对本例中的一些概念没有完全理解也没有关系,继续下一步,很容易理解的!
千万不要呆在原地不动。
下回预告:
将简要说明如何编写简单的Makefile文件来组织我们的源程序,另外还将介绍如何利用gdb对我们的程序进行调试!
精彩不容错过。
附:
添加”destroy“信号处理后的hello_dubuntu2.c
hello_dubuntu2.c
/*本例的主要目的是在窗口中显示一个按钮,
*并且单击按钮退出程序
*/
#include
void
cb_button(GtkWidget*widget,gpointerdata)
{//按钮"button"的回调函数
gtk_main_quit();
}
int
main(intargc,char*argv[])
{
GtkWidget*main_window;//主窗口对象
GtkWidget*button; //将要放置到主窗口中的按钮对象
gtk_init(&argc,&argv);
main_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(main_window),"Hello,Dubuntu2!
");
//设置窗口的默认大小(宽200,高度50)
gtk_window_set_default_size(GTK_WINDOW(main_window),200,50);
button=gtk_button_new_with_label("退出程序");
gtk_container_add(GTK_CONTAINER(main_window),button);
//为"button"连接“单击事件”要调用的回调函数
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(cb_button),NULL);
gtk_widget_show(button);
gtk_widget_show(main_window);
//上边的两句可以合为gtk_widget_show_all(window)
g_signal_connect(G_OBJECT(main_window),"destroy",G_CALLBACK(cb_button),NULL);
gtk_main();
return0;
}
编译:
gcc-ohello_dubuntu2 hello_dubuntu2.c `pkg-config--cflags--libsgtk+-2.0`
大家一起用gtk编程3(初步使用Makefile)
∙5、初步使用Makefile
上回说道,咱们使用GTK创建了一个能够截获事件的GTK程序,本节将简单地介绍一下如何使用Makefile来组织我们的源程序,使用Makefile是基于如下几个原因:
∙能实现从无限简单到无穷复杂的软件工程组织
∙能方便地与众多的Linux命令与实用程序集成,当然也包括Vim与emacs
∙还有很多,就留给读者自己探索吧...
笔者在这里介绍Makefile的主要目的是想让大家知道Linux下有这样一个工具,使用它确实很方便,并且希望大家在有需要的时候能够想到它。
总的来说,Makefile是使用一系列的依赖关系和时间值,来决定是否对一个目标进行重构建;不废话了,来看看我们的Makefile文件长什么样:
Makefile
注意:
Makefile文件如果从网页上直接拷贝,往往不能成功正常使用,请从下边的附件中下载可用的文件。
CC=gcc
PROG_NAME=hello_dubuntu2
INCS=
SRCS=hello_dubuntu2.c
#从xx.c文件得到xx.o文件
OBJS=${SRCS:
.c=.o}
#编译GTK程序时要用到的库
LIBS=gtk+-2.0
#----用户修改区域结束
#-O2
CFLAGS=`pkg-config--cflags${LIBS}`-g-Wall
LDFLAGS=`pkg-config--libs${LIBS}` -g-Wall
all:
${PROG_NAME}
${PROG_NAME}:
${OBJS}
${CC}-o${PROG_NAME}${OBJS}${LDFLAGS}
#注意:
上边”${CC}"的前边有一个TAB键,而不是空格
#如果有头文件进行修改,则自动编译源文件
${OBJS}:
${INCS}
.c.o:
${CC}-c$< ${CFLAGS}
clean:
rm-f*.o ${PROG_NAME}
rebuild:
cleanall
编译:
将此Makefile文件与上一节的hello_dubuntu2.c文件放在同一个文件夹下,然后运行如下命令即可编译出hello_dubuntu2可执行文件:
make
程序注释:
1)刚开始的几行定义了几个变量,比如用CC来代替真正的gcc编译器,这样当想换别的编译器来编译我们的程序时直接改变CC变量的值就OK了。
其它的:
∙CC指代用来编译程序的编译器,这里使用gcc
∙RPOG_NAME指代最终要生成的可执行文件名,需手工填入
∙INCS指代工程文件中所自定义的所有头文件,需手工填入
∙SRCS指代所有使用到的源文件,需手工填入
∙OBJS是通过.c文件得到的.o文件,因为每个.c文件都将编译生成一个对应的.o文件,自动生成
∙LIBS用来指代编译GTK程序时需要使用到的GTK相关库,一般使用默认的gtk+-2.0即可,需手工填入
∙CFLAGS用来指代编译程序时使用到的一些编译选项,-g表示生成调试信息以供GDB使用,-Wall表示生成编译时的警告信息(W表示Warning,all表示全部)
∙LDFLAGS用来指代进行程序连接时使用到的一些选项
以上这些变量,将在Makefile的剩余部分使用${xxx}的形式进行引用。
2)关于“目标”:
“依赖关系”
从“all:
${PROG_NAME}”这一句开始,Makefile就开始使用目标:
依赖的关系来处理真正的程序编译了;而它们下边以TAB键开始的行就是满足依赖关系后要运行的程序(注意:
是TAB键,不是空格)。
具体笔者就不详细描述了,有兴趣的读者可以参考下边推荐的教程。
3)关于“.c.o:
”语句:
这句话的意思就是说,当遇到一个.c文件,那么使用它下边的命令“ ${CC}-c$< ${CFLAGS}”将.c文件编译为.o文件;命令中$<用来代替对应的.c文件的文件名。
4)关于"clean"和"rebuild":
这两个者伪目标,必须使用"makeclean"或"mak
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 大家 起用 gtk 编程
![提示](https://static.bdocx.com/images/bang_tan.gif)