ImageVerifierCode 换一换
格式:DOCX , 页数:34 ,大小:101.73KB ,
资源ID:11639991      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11639991.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(QT和GTK+.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

QT和GTK+.docx

1、QT和GTK+GTK+图形界面编程本章将介绍Linux下的图形界面编程,重点介绍基于C语言的具有面向对象特征的GTK+图形界面编程。主要介绍GTK+图形界面应用程序的框架、基本原理、常用控件的使用。本章重点:GTK+程序的基本结构。事件和消息处理。常用控件的使用。本章难点:理解GTK+应用程序的基本原理。熟悉常用控件的基本用法。12.1 Linux下的图形界面编程12.1.1 Qt和GTK+虽然Linux下的大多数开发是基于字符界面的,但在Linux环境下也可以开发出美观大方的图形界面。经过多年的发展,目前已经存在多种用于在Linux下开发图形界面程序的开发包,其中较为常用的是Qt和GTK+。

2、Qt是一个跨平台的图形用户界面开发库,它不仅支持Linux操作系统,还支持所有类型的UNIX以及Windows操作系统。Qt良好的封装机制使它模块化程度非常高,可重用性很强,Qt提供了丰富的API供开发人员使用。使用Qt开发的图形用户界面程序具有良好的稳定性和健壮性。桌面环境KDE(K Desktop EnVironment即K桌面环境)就是使用Qt作为其底层库开发出来的。由于Qt使用C+面向对象编程语言作为其开发语言,而许多在Linux下从事开发的程序员更喜欢或更习惯于用C语言。GTK+使用C语言作为开发语言。它基于LGPL授权,因此GTK+是开放源代码而且完全免费的。GTK+简单易用,执行

3、效率高。基于这些原因,GTK+拥有为数众多的拥护者。Linux的桌面环境GNOME就是建立在GTK+基础上。GTK+简介图12-1GTK+在几种相关的开发库中的位置。图12-1中每层除了与其上下相邻的两层有联系外,似乎与其他层没有关系。实际上,任何上层都可以调用位于它下面的各层提供的函数。例如,GTK+不仅可以调用GDK函数,也可以调用glib和C库函数。下面按层作简单的介绍,具体说明如表12-1所示。表12-1各层的具体含义层具 体 描 述C有两类C库函数可供调用,一类是标准C的库函数,如printf、scanf;另一类是Linux的系统调用,如open、read、write、forkgli

4、bglib是GDK、GTK+、GNOME应用程序常用的库。它包含内存分配、字符串操作、日期和时间、定时器等库函数,也包括链表、队列、树等数据结构相关的工具函数X它是控制图形显示的底层函数库,包括所有的窗口显示函数、响应鼠标和键盘操作的函数GDKGDK(GIMP绘图包)是为了简化程序员使用X函数库而开发的。X库是其低层函数库,GDK对其进行了包装,从而使程序员的开发效率大为提高GTK+GTK+就是GIMP工具包,它把GDK提供的函数组织成对象,使用C语言模拟出面向对象的特征,这使得用它开发出来的图形界面程序更为简单和高效。GTK+的一个重要组成部分是widget(控件,也称为小部件),按钮、文本

5、编辑框、标签等都是widgetGNOMEGNOME库是对GTK+的扩展,GNOME桌面环境用来控制整个桌面。GNOME使用GNOME对象和函数与桌面小部件交互,基本小部件由GTK+处理。GNOME为了方便程序员还增加了一些专门的小部件ApplicationApplication即应用程序,它完成窗口的初始化,创建并显示窗口,进入消息循环,等待用户使用鼠标或键盘进行操作简单地说,GTK+就是用C语言编写的用于开发图形界面程序的函数库。GTK+来源于GIMP(GNU Image Minipulation Program 即GNU图像处理程序)。GTK+在GDK(GIMP Drawing Kit 即

6、GIMP绘图包)基础上创建,对它进行封装。GTK+简单易用,它设计良好,灵活而富有扩展性。它是自由软件,这意味着它不仅开放源代码,而且还可以免费使用。由于它使用C语言作为其开发语言,而C语言是跨平台的,因此GTK+几乎可以在任何操作系统上使用。在安装Federo Core或者Red Hat Linux系列操作系统时,如果选择了安装应用程序开发包,那么操作系统安装完毕后,GTK+开发包就已经安装好了。如果没有安装,请从网络上(http:/www.gtk.org)免费下载一份GTK源代码并安装到系统上,也可以插入Linux安装光盘在系统提示下进行安装。由于安装过程非常简单,这里就不再赘述了。12.

7、2 一个简单的例子先来看一个简单的GTK+图形界面程序的例子,了解这类程序的一般框架。这个程序创建了一个窗口,并在窗口中放置了一个按钮,实现代码如例12-1所示。例12-1 gtkwin.c#include/*定义回调函数hello,单击按钮时系统自动调用*/void hello(GtkWidget *widget,gpointer *data)g_print(button clicked and data = %sn,(char *)data);/*定义回调函数destroy,关闭窗口时系统自动调用*/void destroy(GtkWidget *widget,gpointer *data

8、) gtk_main_quit();int main(int argc,char *argv)/*定义指向控件的指针*/GtkWidget *window;GtkWidget *button;/*初始化图形显示环境*/gtk_init(&argc,&argv);/*创建窗口,并设置当关闭窗口时,要执行的回调函数*/window = gtk_window_new(GTK_WINDOW_TOPLEVEL);g_signal_connect(GTK_OBJECT(window),destroy,GTK_SIGNAL_FUNC(destroy),NULL);/*设置窗口的属性*/gtk_contain

9、er_border_width(GTK_CONTAINER(window),20);/*创建按钮,并设置当单击按钮时,要执行的回调函数*/button = gtk_button_new_with_label(Hello World);g_signal_connect(GTK_OBJECT(button),clicked,GTK_SIGNAL_FUNC(hello),I am from button);/*将按钮加入到窗口中*/gtk_container_add(GTK_CONTAINER(window),button);/*显示按钮和窗口*/gtk_widget_show(button);gt

10、k_widget_show(window);/*进入消息处理循环*/gtk_main();return 0;编译并运行:rootmci tmp# gcc -o gtkwin gtkwin.c pkg-config -libs -cflags gtk+-2.0rootmci tmp# ./gtkwin注意:编译命令中的字符串pkg-config -libs -cflags gtk+-2.0两边是反引号(在键盘上位于数字字符1的左边)。运行程序,显示如图12-2所示的界面:图12-2 运行界面程序说明。(1)所有的GTK+程序中都必须包含头文件gtk/gtk.h,它声明了所有GTK+编程中要使用的

11、常量、数据结构和函数。(2)所有GTK+程序开始都要调用函数gtk_init(gint *argc,gchar * argv)。该函数定位和打开图形显示,并对颜色、信号等进行初始化。在命令行输入的参数由该函数传递给GTK+,该函数读取并获得与它有关的命令行参数。(3)函数gtk_window_new(GTK_WINDOW_TOPLEVEL)用于创建顶级窗口,GTK+程序的主窗口被称为顶级窗口。虽然一个程序可以创建多个顶级窗口,但通常只创建一个。(4)图形界面下,用户的任何一个操作(如单击鼠标左键,按下键盘上的某个键)都称为发生了一个事件,GTK+都有相应的消息信号产生,如果程序中定义了处理该消

12、息信号的函数,在事件发生后,消息信号处理函数会自动调用。这样的消息信号处理函数也称为回调函数,因为这种函数虽然是在程序里定义,但程序中并没有显式调用而是由系统在事件发生后自动调用。hello()和destroy()就是两个处理消息的回调函数。destroy函数中调用了GTK+函数gtk_main_quit,它使程序退出gtk_main()并完成一些清理工作。g_signal_connect函数用于在控件和消息处理函数间建立关联,该函数的第一个参数为产生消息的控件,第二个参数是消息名,第三个参数是消息发生后要调用的函数名,第四个是传递给消息处理函数的参数,可以为空值(即NULL)。关于消息和回调

13、函数的详细内容请参考下一节。(5)gtk_container_border_width函数用于设置窗口边框的宽度,这是一个设置窗口属性的函数。(6)gtk_button_new_with_label函数创建一个带文本标签的按钮,它完成内存分配,并把所分配到的内存的首地址赋给GtkWidget类型的指针。(7)函数gtk_container_add通知GTK+将按钮加入到主窗口中,函数gtk_widget_show用于显示控件。(8)gtk_main()使GTK+进入消息处理循环。每个GTK+应用程序都有一个gtk_main函数,该函数使程序进入休眠状态。当有事件发生,如果程序中有相应的处理函数

14、,gtk_main()就调用相应的消息处理函数。(9)为了方便编译,可以在源程序所在目录下编写一个Makefile文件:CC=gccprogram=gtkwin#PATH += /usr/include/gtk2.0LDLIBS=pkg-config -libs gtk+-2.0CFLAGS= -Wall -g pkg-config -cflags gtk+-2.0$(program):$(program).o$(CC) $(LDLIBS) $(program).o -o $(program)$(program).o:$(program).c$(CC) $(CFLAGS) -c $(progr

15、am).cclean:-rm -f $(program)-rm -f *.o此时编译程序可以简化为:rootmci tmp# make要删除编译所产生的中间文件和可执行文件,可以执行命令:rootmci tmp# make clean如果要编译其他GTK+程序,把Makefile文件中的gtkwin改为相应源程序的文件名即可。Makefile的编写和make命令的使用请参考第5章。例12-1程序中用到了一些GTK+预定义的函数和数据类型,表12-2和表12-3对其作一个简单的介绍。表12-2GTK+预定义的函数前 缀含 义Gglib定义的数据结构gglib声明的数据类型g_glib定义的函数g

16、tk_GTK+定义的函数GtkGTK+库的对象或数据结构GTKGTK+定义的宏或者常量表12-3GTK+预定义的数据类型GTK+的数据类型C语言数据类型gcharchargintintglonglonggbooleanchargfloatfloatgdoubledoublegucharunsigned charguintunsigned intgulongunsigned longgpointervoid *gint8在任何平台上都是8位的整型gint16在任何平台上都是16位的整型gint32在任何平台上都是32位的整型guint8在任何平台上都是8位的无符号整型guint16在任何平台上都

17、是16位的无符号整型guint32在任何平台上都是32位的无符号整型12.3 消息和回调函数图形用户界面的程序是事件驱动的程序。程序进入gtk_main函数后,等待事件的发生,一旦发生某个事件,相应的信号将产生。如果程序中定义了相应的消息处理函数,系统会自动进行调用。消息处理函数(或称回调函数)的原型是:void callback_func(GtkWidget *widget,gpointer func_data);参数widget指向要接收消息的控件,参数func_data指向消息产生时传递给该函数的数据。函数g_signal_connect在控件和消息处理函数间建立关联,该函数的原型是:g

18、ulong g_signal_connect(GtkObject *object,gchar *nameGcallback callback_func,gpointer func_data);各参数说明如下。object:指向产生消息的控件。name:消息或事件的名称。callback_func:事件发生后要执行的回调函数。func_data:传递给回调函数的数据,与callback_func()的第二个参数相同。该函数的返回值用于区分一个控件的一个事件对应的多个处理函数。一个控件上可以发生多个事件,比如单击一个按钮,双击一个按钮。对于一个控件上的每个事件可以有0个、1个或多个处理函数。该事件

19、发生时,将按声明的顺序逐个调用这些函数。对应于某个事件,如果控件没有定义处理函数,那么事件发生时将没有响应,系统忽略此事件。还有一个与g_signal_connect()类似的函数:gint g_signal_connect_swapped(GtkObject *object,gchar *nameGCallback callback_func,GtkObject *slot_object);它的第四个参数指向一个GTK+控件的指针。它与g_signal_connect()的区别在于相应的回调函数只有一个参数:void callback_func(GtkObject *object);通常ob

20、ject指向一个控件。可以在上一节的例子中gtk_container_add(GTK_CONTAINER(window),button);之前加上一条语句:g_signal_connect(GTK_OBJECT(button),clicked,GTK_SIGNAL_FUNC(gtk_widget_destroy),GTK_OBJECT(window);则对应于button按钮的clicked事件有两个处理函数,一个是程序中定义的回调函数hello,还有一个是GTK+预定义的gtk_widget_destroy()。gtk_widget_destroy()的作用与程序中的destroy()相同。

21、编译运行程序,如果单击按钮,系统先调用hello函数(因为它先与button控件建立关联)在命令行上打印出一行消息,然后调用gtk_widget_destroy()退出程序。如果要删除控件和消息处理函数的关联,可以调用g_signal_disconnect(),该函数的原型是:void g_signal_handler _disconnect(GtkObject *object ,gulong id);参数说明如下。object:要删除消息处理函数的控件。id:g_signal_connect()或g_signal_connect_swapped()函数的返回值。下面这个函数可以删除某控件的所

22、有消息处理函数:void g_signal_handlers_destroy(GtkObject *object);12.4 GTK+的面向对象机制对于那些没有接触过面向对象语言的读者来说,本节的内容可能比较难以理解。不过没有关系,这并不会影响后面内容的掌握。介绍本节的内容只是为了简单地介绍一下GTK+中是如何模拟面向对象机制的。面向对象编程语言(如C+、Java)把数据和对数据的操作封装在一起构成类,由类来产生对象,由对象来构建程序。类中对数据的操作由函数来完成,这种函数被称为成员函数或方法。面向对象语言通过继承、重载、多态等机制大大增强软件的可重用性和可维护性。C语言虽然不是面向对象语言,

23、但GTK+以及建立在其上的GNOME库却使C语言模拟出了一些典型的面向对象机制,如封装、继承和多态。为了较好的理解GTK+程序,了解GTK+中的面向对象机制也是很有必要的。对象的一个主要特性是将数据和对数据的操作封装在一起,受保护的私有数据只能通过成员函数才能访问和修改。GTK+使用C语言的结构体来模拟对象,虽然有些缺陷但基本模拟出了对象的基本特征。有了对象作为基础,通过在对象中加入新的数据和对这些数据进行操作的函数,就实现了继承。被继承的类(类相当于一种自定义数据类型,由类来定义对象)称为父类或基类,由基础类派生出来的类称为子类或派生类。子类继承了父类的数据和对这些数据进行操作的成员函数,并

24、加入了新的数据和成员函数,实现了对原有父类的重用和扩展,从而实现了可重用性和可扩展性。GTK+中有一个类,它是所有其他类的父类,这个类是GtkObject。GTK+中最常用的按钮控件也是一个类,它继承自GtkObject。它与GtkObject的继承关系是:GtkObject GtkWidget GtkContainer GtkBin GtkButton使用C语言如何模拟继承呢?对象(类)是由结构体模拟的,每一个子类所在的结构体都包含了父类的结构体,子类结构体的第一个成员是其父类结构体,示例代码如下:struct GtkObject ;struct GtkWidget GtkObject ob

25、ject;struct GtkContainer GtkWidget widget;struct GtkBin GtkContainer container;struct GtkButton GtkBin bin;从上述代码可以看到,每个子类都包含了其父类的所有数据,并且父类的数据位于子类结构体的开始。对于一个GtkButton 类型的button控件变量(它其实是一个指向GtkButton结构体的指针),通过宏GTKBIN(button)就得到了其父类(GTK+预定义的宏GTKBIN其实是进行了强制类型转换,把一个GtkButton类型的指针强制转化为GtkBin类型的指针)。例12-1中的

26、GTK_OBJECT(button)就是进行了这样的转换。为了便于理解,我们写一个测试程序,如例12-2所示。例12-2 test.c#include#include#define FATHER(child) (struct Father *)(child)void print1(int i)printf(this is father and i = %dn,i);void print2(int i)printf(this is child and i = %dn,i);struct Father int a;void (*pointer1_to_function)(int);struct C

27、hild struct Father f;int b;void (*pointer2_to_function)(int);void father_member_funtion(struct Father *f,char *string)printf(n);f-pointer1_to_function(f-a);printf(%snn,string);int main()struct Child *p_child;p_child = (struct Child *)malloc(sizeof(struct Child);p_child-f.a = 10;p_child-f.pointer1_to

28、_function = print1;p_child-b = 20;p_child-pointer2_to_function = print2;p_child-pointer2_to_function(p_child-b);struct Father *p_father = FATHER(p_child);p_father-pointer1_to_function(p_father-a);father_member_funtion(p_father,hello);return 0;程序输出:this is child and i = 20this is father and i = 10thi

29、s is father and i = 10hello程序说明。(1)结构体Father相当于GTK+中的父类,而结构体Child就相当于子类。结构体Father有一个成员变量和一个成员函数(实际上是一个指向函数的指针,函数指针的内容请参考第4章4.3.4指针和函数一节)。结构体Child在其头部包含了结构体Father,并增加了一个成员变量和一个成员函数(也是一个函数指针)。结构体Father和Child模拟了类,Child模拟继承了Father。(2)程序定义了一个指向结构体Child的指针,并对Child中的成员进行了初始化。然后调用了结构体Child的成员函数pointer2_to_f

30、unction。通过宏FATHER(p_child)将指针p_child强制转换为指向Father结构体的指针。事实上,p_child和p_father的值是一样的,它们都保存着结构体Child的首地址。宏FATHER(p_child)类似于例12-1程序gtk_container_add(GTK_CONTAINER (window),button)中的GTK_CONTAINER(window)。我们注意到,p_father调用了它自己的成员函数pointer1_to_function。(3)father_member_funtion函数是类Father成员函数的另一种实现方法,这种方法避免了在结构体Father中保存函数指针。GTK+定义了很多生成对象或对对象进行操作的函数。例如,下面就创建了一个对象:GtkWidget *button;button = gtk_button_new_with_label(label);所有创建对象的函数在其名称上都有new这个词。函数gtk_button_new_with_label创建了一个显示文本的

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1