原文地址:http://blog.programet.org/2010/08/gtk-0.html
GTK+是当下流行的图形界面库之一,使用GTK+可以方便地构造出应用程序界面。叶子觉得GTK+很好用,在这里推荐给大家,并留下自己的一些使用心得。希望你也喜欢~
在Programet这个系列中,你可以看到GTK+通俗的介绍,了解使用方法和常用API,我们希望能对你有所帮助。下面是这个系列的内容线索(本系列不断更新中,这个列表可能随更新而有少量变化):
- 构建GTK+编译环境
- GTK+“Hello World”——对GTK+运作机制的通俗介绍
- 使用GtkBuilder、界面设计器Glade和其他GTK+组件
- GTK+常用物件及API(窗口)
- GTK+常用物件及API(文本)
- GTK+常用物件及API(按钮)
- GTK+常用物件及API(其他)
- GLib中的小工具
- 使用gettext实现国际化和制作语言包
- 【高级主题】使用GDK访问底层屏幕和事件
- 【高级主题】使用gtk-pixbuf处理图像和图像文件
- 【高级主题】使用GIO中的GSocket访问网络
- 【高级主题】使用cairo绘图
上面的列表中并没有“GTK+介绍”一项,因为我要在这篇文章后半部分完成它!
GTK+究竟能做什么
GTK+是图形界面库,能帮助我们简洁方便地绘制窗口和里面的输入框、按钮等等。这能减少我们很多麻烦——有经验的童鞋可能深有体会,图形界面几乎是应用程序编写中最繁琐的部分。图形界面库就是为了方便我们组织界面而出现的,使用它可以大大减少我们花在组织界面上的代码量。
同时,GTK+可以配合界面设计器Glade,换句话说,做界面不用敲冗长的代码,界面可以画出来!
更重要的是,GTK+是跨平台的。只要代码写得标准,在Windows、Linux和Mac OS下,不用做任何修改就可以展现出同样的界面,方便吧~
GTK+支持的
GTK+是一个开源跨平台的库,支持很多平台,这里就不一一列举了。它遵循LGPL协议,也就是说我们可以自由地使用它,使用它制作的程序可以自行选择开源与否。
GTK+是用C语言编写的,很多GTK+应用程序也使用C语言完成。但如果你讨厌C语言的话,你同样可以选用其他多种语言,包括C++、Java、Python等等,甚至还可以是PHP。而且在各种语言中的API很相似,这让我们在各种语言下玩GTK+变得很方便。
谁在用GTK+
GTK+现在为很多软件所使用,最典型的是Linux桌面环境GNOME和Xfce,包括在它们中运行的众多软件(很多时候GNOME和Xfce软件可以混用,因为他们都是GTK+的)。
还有号称“开源PS”的GIMP、矢量图编辑器Inkscape等等,还有只是使用部分GTK+库(尤其是GLib)的众多软件,还有偷偷拿GTK+代码来用的软件……
与GTK+相似的图形界面库
目前,还有很多流行的图形界面库:
- MFC——微软的一个C++库,很多人用,但功能落后,也被讽刺为“半成品”。
- Qt——大红大紫的一个图形界面库,各方面表现都很好。现归属于Nokia。(传说很久很久以前QT和GTK+的支持者喜欢对骂……)
- WxWidgets——个人认为这个库灰常强大!它在不同操作系统中都可以生成“原生”的界面,甚至不需要运行库!只是有人说不稳定……
还有其他的一些,这里就不提了吧。
毫无疑问的是,GTK+是它们中很有特点的一个。你很难找出第二个C语言图形界面库。GTK+以架构严谨优秀高效著称,是GNU项目的一部分,像是很标准的GNU式的开源项目。它和GNU项目中的其他部分配合良好,遇到麻烦时,常常可以让其他库帮忙。
GTK+的历史与前景
GTK+是1999年开始发展的一个项目,在图形界面库中算很年轻的,但是发展飞速,以至于网络上对其的描述都难以跟上其发展(现在搜索到的很多描述不正确)。GTK+一直由社区维护,但同时又备受众多商业公司青睐,应用领域在不断扩展中。
有关本系列
在这一系列文章中,GTK+原生语言——C语言将被用来举例,其他语言使用方法类似,具体请参见不同语言的文档。这也要求读者能熟练运用C语言。
文章中的例子使用Windows下的GTK+ 2.16(GLib 2.24)编译通过,并特别照顾Windows下的配置、使用,相较而言,在Linux下的配置、使用简单一些。
原文地址:http://blog.programet.org/2010/08/gtk-1.html
这一部分介绍的是在Windows/Linux下配置GTK+(C语言)编译及运行环境的方法。如果内容存在错误,或者方法不适用与你的电脑,请在下方评论区留言给我,谢谢!
在Linux下配置GTK+编译环境
Linux的X Window是GTK+主要应用的地方,在Linux下配置GTK+应该是比较容易成功的。当然,你的Linux需要有GNOME或Xfce这样的桌面环境(不建议在KDE下运行GTK+应用程序)。
如果你的Linux像Ubuntu这样有一个软件库,那就太方便了,直接安装包libgtk2.0-dev即可。如果不能直接安装软件包,你还可以直接到http://www.gtk.org/download-linux.html下载,那个安装指南会对你有帮助的。
然后是编辑器的问题。像Anjuta这样的编辑器可以直接创建GTK+项目,你可以利用这个功能,很方便。如果你的编辑器不能创建GTK+项目,或者你根本不打算用编辑器,你可以用pkgconfig命令获得你用gcc编译时所需的参数:
- pkg<span style="color:#339933">-</span>config <span style="color:#339933">--</span>cflags <span style="color:#339933">--</span>libs gtk<span style="color:#339933">+-</span><span style="color:#800800">2.0</span>
|
这一系列以后的文章中会用到Glade界面设计器,请安装包glade或到http://ftp.gnome.org/pub/GNOME/sources/glade3/3.6/下载Source来编译。要注意的是,Glade本身也是一个GTK+应用程序,需要在GTK+的桌面环境中运行。
在Windows下配置GTK+编译环境
在Windows下配置编译环境就有些麻烦。这里看来要用支持创建GTK+项目的编辑器来帮忙了。
这里介绍在Code::Blocks编辑器和MinGW GCC编译器下编译GTK+程序的方法。(其实在Visual Studio下也可以编译GTK+的,但是这里不推荐。)
装好Code::Blocks
如果你不熟悉Code::Blocks,建议看看我以前写的这篇文章。
安装GTK+开发库和Glade界面编辑器
这里介绍一个简单的方法。Glade有的发布版直接包含有GTK+开发库。到Glade主页http://glade.gnome.org/右边的Windows Binaries中找Glade3-x.x.x-with-gtk.exe这样的版本下载安装。建议装到C:\gtk\。
但是可能Glade自带的GTK+开发库不是最新的,无法实现一下高版本的GTK+提供的功能,因此最好到GTK+下载页http://www.gtk.org/download-windows.html下载一个All-in-one bundles。下载下来之后直接解压到刚刚Glade的安装目录即可。
在Code::Blocks中建立GTK+项目
Code::Blocks中,File->New->Project中应该会有GTK+ Project这一选项。按着向导新建即可,但要注意几个地方:项目文件完整路径必须是英文的,Code::Blocks对中文路径和文件名支持不佳;GTK’s location必须指定为你刚刚安装的GTK+开发库所在文件夹。
测试你的编译环境
就拿Code::Blocks为我们自动生成的这段程序做测试吧:
- <span style="color:#339933">#include <stdlib.h></span>
- <span style="color:#339933">#include <gtk/gtk.h></span>
-
- <span style="color:#993333">static</span> <span style="color:#993333">void</span> helloWorld <span style="color:#099000">(</span>GtkWidget <span style="color:#339933">*</span>wid<span style="color:#339933">,</span> GtkWidget <span style="color:#339933">*</span>win<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkWidget <span style="color:#339933">*</span>dialog <span style="color:#339933">=</span> NULL<span style="color:#339933">;</span>
-
- dialog <span style="color:#339933">=</span> gtk_message_dialog_new <span style="color:#099000">(</span>GTK_WINDOW <span style="color:#099000">(</span>win<span style="color:#099000">)</span><span style="color:#339933">,</span> GTK_DIALOG_MODAL<span style="color:#339933">,</span> GTK_MESSAGE_INFO<span style="color:#339933">,</span> GTK_BUTTONS_CLOSE<span style="color:#339933">,</span> <span style="color:#ff0000">"Hello World!"</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_window_set_position <span style="color:#099000">(</span>GTK_WINDOW <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">,</span> GTK_WIN_POS_CENTER<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_dialog_run <span style="color:#099000">(</span>GTK_DIALOG <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_widget_destroy <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- <span style="color:#993333">int</span> main <span style="color:#099000">(</span><span style="color:#993333">int</span> argc<span style="color:#339933">,</span> <span style="color:#993333">char</span> <span style="color:#339933">*</span>argv<span style="color:#099000">[</span><span style="color:#099000">]</span><span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkWidget <span style="color:#339933">*</span>button <span style="color:#339933">=</span> NULL<span style="color:#339933">;</span>
- GtkWidget <span style="color:#339933">*</span>win <span style="color:#339933">=</span> NULL<span style="color:#339933">;</span>
- GtkWidget <span style="color:#339933">*</span>vbox <span style="color:#339933">=</span> NULL<span style="color:#339933">;</span>
-
- <span style="color:#808080; font-style:italic"></span>
- g_log_set_handler <span style="color:#099000">(</span><span style="color:#ff0000">"Gtk"</span><span style="color:#339933">,</span> G_LOG_LEVEL_WARNING<span style="color:#339933">,</span> <span style="color:#099000">(</span>GLogFunc<span style="color:#099000">)</span> gtk_false<span style="color:#339933">,</span> NULL<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_init <span style="color:#099000">(</span><span style="color:#339933">&</span>argc<span style="color:#339933">,</span> <span style="color:#339933">&</span>argv<span style="color:#099000">)</span><span style="color:#339933">;</span>
- g_log_set_handler <span style="color:#099000">(</span><span style="color:#ff0000">"Gtk"</span><span style="color:#339933">,</span> G_LOG_LEVEL_WARNING<span style="color:#339933">,</span> g_log_default_handler<span style="color:#339933">,</span> NULL<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#808080; font-style:italic"></span>
- win <span style="color:#339933">=</span> gtk_window_new <span style="color:#099000">(</span>GTK_WINDOW_TOPLEVEL<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_container_set_border_width <span style="color:#099000">(</span>GTK_CONTAINER <span style="color:#099000">(</span>win<span style="color:#099000">)</span><span style="color:#339933">,</span> <span style="color:#00dd00">8</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_window_set_title <span style="color:#099000">(</span>GTK_WINDOW <span style="color:#099000">(</span>win<span style="color:#099000">)</span><span style="color:#339933">,</span> <span style="color:#ff0000">"Hello World"</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_window_set_position <span style="color:#099000">(</span>GTK_WINDOW <span style="color:#099000">(</span>win<span style="color:#099000">)</span><span style="color:#339933">,</span> GTK_WIN_POS_CENTER<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_widget_realize <span style="color:#099000">(</span>win<span style="color:#099000">)</span><span style="color:#339933">;</span>
- g_signal_connect <span style="color:#099000">(</span>win<span style="color:#339933">,</span> <span style="color:#ff0000">"destroy"</span><span style="color:#339933">,</span> gtk_main_quit<span style="color:#339933">,</span> NULL<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#808080; font-style:italic"></span>
- vbox <span style="color:#339933">=</span> gtk_vbox_new <span style="color:#099000">(</span>TRUE<span style="color:#339933">,</span> <span style="color:#00dd00">6</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_container_add <span style="color:#099000">(</span>GTK_CONTAINER <span style="color:#099000">(</span>win<span style="color:#099000">)</span><span style="color:#339933">,</span> vbox<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- button <span style="color:#339933">=</span> gtk_button_new_from_stock <span style="color:#099000">(</span>GTK_STOCK_DIALOG_INFO<span style="color:#099000">)</span><span style="color:#339933">;</span>
- g_signal_connect <span style="color:#099000">(</span>G_OBJECT <span style="color:#099000">(</span>button<span style="color:#099000">)</span><span style="color:#339933">,</span> <span style="color:#ff0000">"clicked"</span><span style="color:#339933">,</span> G_CALLBACK <span style="color:#099000">(</span>helloWorld<span style="color:#099000">)</span><span style="color:#339933">,</span> <span style="color:#099000">(</span>gpointer<span style="color:#099000">)</span> win<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_box_pack_start <span style="color:#099000">(</span>GTK_BOX <span style="color:#099000">(</span>vbox<span style="color:#099000">)</span><span style="color:#339933">,</span> button<span style="color:#339933">,</span> TRUE<span style="color:#339933">,</span> TRUE<span style="color:#339933">,</span> <span style="color:#00dd00">0</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- button <span style="color:#339933">=</span> gtk_button_new_from_stock <span style="color:#099000">(</span>GTK_STOCK_CLOSE<span style="color:#099000">)</span><span style="color:#339933">;</span>
- g_signal_connect <span style="color:#099000">(</span>button<span style="color:#339933">,</span> <span style="color:#ff0000">"clicked"</span><span style="color:#339933">,</span> gtk_main_quit<span style="color:#339933">,</span> NULL<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_box_pack_start <span style="color:#099000">(</span>GTK_BOX <span style="color:#099000">(</span>vbox<span style="color:#099000">)</span><span style="color:#339933">,</span> button<span style="color:#339933">,</span> TRUE<span style="color:#339933">,</span> TRUE<span style="color:#339933">,</span> <span style="color:#00dd00">0</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#808080; font-style:italic"></span>
- gtk_widget_show_all <span style="color:#099000">(</span>win<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_main <span style="color:#099000">(</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">return</span> <span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
这段程序会建立一个有两个按钮的窗口。Windows下还会另外有个小黑窗口,方便调试用的;指定Build->Select target->Release之后再编译,编译出来的“Release”版本就没有小黑窗口了。
如果你编译失败——不幸,但是你可以在下面留言给我。
在Windows下制作一个GTK+运行环境
你需要明白的是,GTK+是需要运行库的——Linux下一般都会自带有,Windows下就没那么幸运了。如果你的程序需要在别人的电脑上运行,你往往需要附带一个GTK+运行库,运行库的制作方法是把http://www.gtk.org/download-windows.html中的所有Binary组合起来。
为了方便大家,我自己做了一个运行库,经过一定精简(只有中英两种语言),大小13MB(压缩后3MB)。大家可以到这里下载。
用法就是把程序及程序用到的文件放进来,使程序与运行库的那堆dll在同一级文件夹下。然后整个文件夹就可以作为便携软件在不含GTK+的Windows中使用了。
另外,GTK+运行库是支持主题的。你可以为GTK+指定主题,给那些按钮换一个样子。GTK+主题文件位于运行库的\etc\gtk-2.0文件夹中,名为gtkrc。我制作的运行库指定了GTK+使用Windows主题。你可以在网上搜出很多GTK+ themes,使用方法就是替换gtkrc文件。
原文地址:http://blog.programet.org/2010/09/gtk-2.html
这一部分是对最简单的GTK+(C语言)程序的一个解释,并介绍GTK+的基本概念和运作方式。如果内容存在错误,或者方法不适用与你的电脑,请在下方评论区留言给我,谢谢!
几个概念
首先先来解释GTK+中几个基本的概念,以方便将来的分析。
物件(GtkWidget):GTK+中每一个窗口里的组成要素都被视为一个物件,如按钮、文本等等,窗口本身也是一个物件。总之GTK+的界面就是由物件构成的。注意,物件都使用指针来管理,物件外在表现就是一个特定类型的指针。
容器(GtkContainer):物件里的一大类,容器的特点是其内部能够容纳其他物件。容器最基本的功能之一是将各种物件良好地组织起来。GTK+的容器能在大小改变时自动调整内含物件的大小,这使得GTK+能够很智能地相应窗口或其他物件的大小改变。这为我们提供了很大的方便,往往我们不需要指定某个物件的大小,只需说明他所在的容器位置,GTK+会把物件的实际位置和大小自动计算出来(这比MFC强多了!)。
继承、组合:虽然是C语言写的,但GTK+灵活地运用了面向对象思想。GTK+的物件体系中就有继承、组合这样的关系,如窗口(GtkWindow)是由容器(GtkContainer)派生出来的。
类型转换宏:C语言本身没有“继承”这个概念,那么,如果直接把派生的物件直接当做基物件使用,会出现一个编译警告,即“隐式指针类型转换”,但不会出错。为了消除这个警告,需要做指针类型转换。一般情况下类型转换使用类型转换宏。类型转换宏内部会检查物件的继承关系,确定能否进行转换,然后再做显式类型转换。
事件(event):用户的操作,比如按下某个按钮或快捷键,被视为一个事件。
信号(signal):GTK+是基于信号回调(signal-slot)机制的。信号捆绑了一个事件和一个函数,在用户触发这个事件时,这个函数会被调用一次。从这个角度来说,GTK+是基于物件的,即程序围绕物件属性、事件、方法进行。
主循环(main loop):GTK+程序在一个主循环中运行。当一个事件被触发时,它将被插入队列中;在主循环中被触发的事件会被逐个处理(和这个事件绑定的函数被逐个调用);没有事件被触发时,程序就处于等待状态,等待下一个事件被用户触发。直到退出主循环的函数被调用,GTK+程序才结束。
GTK+命名规范
GTK+拥有开源软件的很多特点,比如结构高度严谨,可读性甚好。现在介绍一下GTK+的关键字命名方式,以便阅读一段GTK+程序。
普通变量类型名:全小写写法,以“g”开头,如“gint”。
物件类型名:驼峰写法(首字母大写),以“Gtk”开头,形如“GtkWindow”。在GTK+内部,类型是向下面这样定义的(以GtkWindow为例)。
- <span style="color:#993333">typedef</span> _GtkWindow <span style="color:#099000">{</span> ... <span style="color:#099000">}</span> GtkWindow<span style="color:#339933">;</span>
|
函数名:小写夹下划线写法,以“gtk_”为前缀,形如“gtk_main()”。如果是针对某类物件的函数,则前缀中还有物件类型名,形如“gtk_window_new()”。
常数名:大写夹下划线写法,以“GTK_”为前缀,形如“GTK_WINDOW_TOPLEVEL”。
类型转换宏:大写夹下划线写法,以“GTK_”为前缀。一般来说,宏名字和类型名相仿,比如要把GtkWindow*类型的物件转换为GtkContainer*类型,就使用宏“GTK_CONTAINER()”。
GTK+的“Hello World”
下面这段程序是GTK+的Hello World,它创建一个普通窗口,里面只有一句“Hello, World”。在前文的基础上,可以分析一下这一段Hello World。
- <span style="color:#666666; font-style:italic">
-
- <span style="color:#339933">#include <gtk/gtk.h>
-
- <span style="color:#993333">int</span> main <span style="color:#099000">(</span><span style="color:#993333">int</span> argc<span style="color:#339933">,</span> <span style="color:#993333">char</span> <span style="color:#339933">*</span>argv<span style="color:#099000">[</span><span style="color:#099000">]</span><span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkWidget <span style="color:#339933">*</span>window<span style="color:#339933">;</span>
- GtkWidget <span style="color:#339933">*</span>label<span style="color:#339933">;</span> <span style="color:#666666; font-style:italic">
-
- <span style="color:#666666; font-style:italic">
- gtk_init <span style="color:#099000">(</span><span style="color:#339933">&</span>argc<span style="color:#339933">,</span> <span style="color:#339933">&</span>argv<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
-
- <span style="color:#666666; font-style:italic">
- window <span style="color:#339933">=</span> gtk_window_new <span style="color:#099000">(</span>GTK_WINDOW_TOPLEVEL<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
- <span style="color:#666666; font-style:italic">
- gtk_window_set_title <span style="color:#099000">(</span>GTK_WINDOW <span style="color:#099000">(</span>window<span style="color:#099000">)</span><span style="color:#339933">,</span> <span style="color:#ff0000">"Hello World"</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
- <span style="color:#666666; font-style:italic">
- g_signal_connect <span style="color:#099000">(</span>window<span style="color:#339933">,</span> <span style="color:#ff0000">"destroy"</span><span style="color:#339933">,</span> G_CALLBACK <span style="color:#099000">(</span>gtk_main_quit<span style="color:#099000">)</span><span style="color:#339933">,</span> NULL<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
-
- <span style="color:#666666; font-style:italic">
- label <span style="color:#339933">=</span> gtk_label_new <span style="color:#099000">(</span><span style="color:#ff0000">"Hello, World"</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
- gtk_container_add <span style="color:#099000">(</span>GTK_CONTAINER <span style="color:#099000">(</span>window<span style="color:#099000">)</span><span style="color:#339933">,</span> label<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
-
- <span style="color:#666666; font-style:italic">
- gtk_widget_show_all <span style="color:#099000">(</span>window<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
- gtk_main <span style="color:#099000">(</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#b1b100">return</span> <span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
程序内容很简洁,它只处理一个事件:关闭窗口。但是这个程序已经摆出了GTK+程序主函数编写的基本形式:使用gtk_init()初始化;建立窗口、组织窗口内容并连接信号;显示窗口;进入主循环。此外,编写回调函数并动态修改窗口内容通常也是必须的。基本所有GTK+程序都遵循这个规律。
可以想见的是,建立窗口、组织窗口内容是非常麻烦的事情。于是界面设计器应运而生,使得组织界面的工作不再由代码完成。下一部分内容会介绍使用界面设计器Glade的方法。
另外,有关GTK+物件、函数、常数的说明都可以在GTK+参考中找到。记得收藏GTK+参考的网址http://library.gnome.org/devel/gtk/stable/index.html,将来查找函数就靠它了!
原文地址:http://blog.programet.org/2010/09/gtk-3.html
这一部分包括GTK+相关组件的简要介绍,和界面设计器的使用方法。如果内容存在错误,或者方法不适用与你的电脑,请在下方评论区留言给我,谢谢!
GTK+的姊妹库
准确地说,GTK+仅指一个界面物件库。为了制作GTK+,一些副产品相继诞生,比如C语言界很有名的的GLib库。这些GTK+的“姊妹库”都是GTK+所依赖的,而且,制作GTK+程序时可能需要直接使用这些库。
- GLib:目前最好的C语言数据结构库之一。除数据结构外,它还包括许多常用小工具,比如多线程管理、定时器。GTK+界面无关的部分基本都被并入GLib中。
- GIO:GLib库相对独立的一部分,专门处理输入输出流。新版本的GIO还包括了网络连接功能。
- GObject:GLib库相对独立的一部分,维护一套对象系统。GTK+疯狂地使用这个系统。
- ATK:ATK提供一组查看和控制接口以方便对GTK+程序的访问。
- pango:负责处理GTK+中和字体有关的部分。
- cairo:著名的2D渲染库,被Firefox等很多程序使用。它也是目前GTK+使用的2D渲染库,通过它可以进行矢量绘图。
- gdk-pixbuf:GDK的一个部分,提供了一组位图函数,包括位图变换、位图文件读写等等。
- GDK:提供一组接口,把GTK+从桌面系统细节中隔离出来。它是一组底层函数,可以直接访问窗口细节。GTK+系统有关的部分多数在这里。
这些库的API参考都可以在GNOME参考(http://library.gnome.org/devel/references.html.zh_CN)中找到。
还有一些库是GTK+依赖的第三方库,下面是几个重要的。
- gettext:国际化库。主要用于制作多语言程序。运行时gettext自动识别操作系统语言,然后从已有语言包中选择一个最合适用户的。
- iconv:字符集转换库。GTK+内部使用UTF-8字符集,有时需要字符集转换。
GTK+内部构成
GTK+本身只负责界面组织。它提供的函数大致可分为三类,物件(Widget)、对象(Object)和其它工具函数。
工具函数提供一些与界面关系密切的实用功能,比如剪贴板读写。
对象是一些功能更加复杂的不可见元素,它们和界面息息相关,比如GtkBuilder。
界面设计器Glade
通过代码来组织界面繁琐而不直观,因而有人为GTK+做了一款界面设计器,名为Glade,现已成为GTK+最重要的辅助工具。
接下来用一个计算器制作的实例来讲解GTK+界面设计器的使用方法。
打开Glade。Glade会自动新建一个文件,新建后会弹出对话框设置文件格式,应选用GtkBuilder。
首先建一个窗口。在左栏中找到“窗口”一项,点一下即可。中间部分的黑框即为窗口中的内容。
下面要组织窗口中的内容了。要注意的是,一个灰色区域只能放置一个物件。如果需要放置多个物件,可以使用水平框、垂直框或表格物件,这些容器可以把一个灰色区域分成多个。
添加Spin按钮(Spin按钮用于输入数字)、表格、按钮等物件,可以把界面画成想要的样子,在右下方的属性设置中,可以设置物件的各种属性。在“常规”选项卡中,可以设置一些重要的初始值,物件名等。注意:需要动态更改的物件,物件名很重要。
“包装”选项卡负责物件的间距控制和大小改变方式等。GTK+在窗口大小改变时会智能地调整物件大小,其依据的就是这个选项卡里的设置。
计算器的界面成形了。记得经常保存,Glade有时会比较脆弱。
注意:在输入完某项属性之后务必使输入焦点离开当前输入区,然后才可以保存文件,否则当前输入区的更改不会被立即保存到文件中。
载入界面
Glade文件的本质是个XML文件,这个文件可以用GtkBuilder对象载入并生成界面。下面这样写可以载入一个Glade文件。
- GtkBuilder<span style="color:#339933">*</span> gtk_load_glade<span style="color:#099000">(</span>gchar<span style="color:#339933">*</span> filename<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkBuilder <span style="color:#339933">*</span>gb<span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
- gb<span style="color:#339933">=</span>gtk_builder_new<span style="color:#099000">(</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#666666; font-style:italic">
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span><span style="color:#339933">!</span>gtk_builder_add_from_file<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>filename<span style="color:#339933">,</span>NULL<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#b1b100">return</span> NULL<span style="color:#339933">;</span>
- <span style="color:#666666; font-style:italic">
- gtk_builder_connect_signals<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>NULL<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
- <span style="color:#b1b100">return</span> gb<span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
载入后还需要还需要获得已载入的物件地址,并将储存在物件指针里以便以后动态更改物件。一个聪明的策略是使指针名字和物件在Glade里设置的名字一样。用函数gtk_builder_get_object()可以获得指定名字的物件地址。为了简便,可以写一段宏代替冗长的函数调用。下面这段代码演示了获得主窗口(名为WMain)和Spin按钮(名为SAns)地址的方法。
- <span style="color:#339933">#define w_(builder,type,name) name=GTK_##type(gtk_builder_get_object(builder,#name))</span>
-
- GtkWindow <span style="color:#339933">*</span>WMain<span style="color:#339933">;</span>
- GtkSpinButton <span style="color:#339933">*</span>SAns<span style="color:#339933">;</span>
-
- <span style="color:#993333">void</span> cal_get_widgets<span style="color:#099000">(</span>GtkBuilder<span style="color:#339933">*</span> gb<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- w_<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>WINDOW<span style="color:#339933">,</span>WMain<span style="color:#099000">)</span><span style="color:#339933">;</span>
- w_<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>SPIN_BUTTON<span style="color:#339933">,</span>SAns<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
主窗口开始时是不显示的,应该用下面这个函数把它显示出来。下面这个函数只能在获得物件地址后执行。
- <span style="color:#993333">void</span> cal_widget_init<span style="color:#099000">(</span><span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- gtk_widget_show<span style="color:#099000">(</span>GTK_WIDGET<span style="color:#099000">(</span>WMain<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
编写回调函数
现在的主要任务就是编写回调函数——这些函数才是程序的主角。在某个事件被触发时,对应的函数会被执行。这个函数可以在Glade中指定。在Glade中选定某个物件,然后在右下角“信号”选项卡中选择一个合适的事件,在“操作句柄”列填入函数名。
下面为窗口WMain指定destroy事件的回调函数on_WMain_destroy()。
然后编写一个函数on_WMain_destroy()。在Windows下,这个函数要加上修饰词G_MODULE_EXPORT。
- G_MODULE_EXPORT <span style="color:#993333">void</span> on_WMain_destroy<span style="color:#099000">(</span>GtkObject<span style="color:#339933">*</span> widget<span style="color:#339933">,</span> gpointer user_data<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- gtk_main_quit<span style="color:#099000">(</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
这个回调函数只是退出程序而已。最后献上一段main()。
- <span style="color:#993333">int</span> main<span style="color:#099000">(</span><span style="color:#993333">int</span> argc<span style="color:#339933">,</span> <span style="color:#993333">char</span> <span style="color:#339933">*</span>argv<span style="color:#099000">[</span><span style="color:#099000">]</span><span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkBuilder <span style="color:#339933">*</span>gb<span style="color:#339933">;</span>
-
- gtk_init<span style="color:#099000">(</span><span style="color:#339933">&</span>argc<span style="color:#339933">,&</span>argv<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- gb<span style="color:#339933">=</span>gtk_load_glade<span style="color:#099000">(</span><span style="color:#ff0000">"gtk-cal.glade"</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>gb<span style="color:#339933">==</span>NULL<span style="color:#099000">)</span><span style="color:#b1b100">return</span> <span style="color:#339933">-</span><span style="color:#00dd00">1</span><span style="color:#339933">;</span>
- cal_get_widgets<span style="color:#099000">(</span>gb<span style="color:#099000">)</span><span style="color:#339933">;</span>
- cal_widget_init<span style="color:#099000">(</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- gtk_main<span style="color:#099000">(</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#b1b100">return</span> <span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
这个计算器程序目前只完成了最基本的部分,这个系列后续的文章会把它做完。有关回调函数、物件函数的信息,请参考GTK+ API参考。
原文地址:http://blog.programet.org/2010/10/gtk-4.html
这一部分内容介绍有关GTK+常用窗口类物件的一些函数。如果对内容有疑问,请在下方留言,谢谢!
GTK+的窗口
窗口是GTK+最基本的物件之一,物件要被放在窗口里显示。GTK+里,常用的窗口包括顶级窗口(GtkWindow)、对话框(GtkDialog)和消息对话框(GtkMessageDialog)等。
GTK+有关窗口的操作很多,绝大多数情况下可以满足自定义窗口的需求;但有时候还是不可避免要直接访问底层库GDK。要注意的是,GdkWindow与GtkWindow有很大差异,GdkWindow指一个显示区域,每一个可显示的GTK+物件都对应一个GdkWindow,阅读文档时两者不可混淆。
窗口类物件在Glade中得到了良好的支持,复杂的窗口建议直接用Glade创建。
简易消息对话框
消息对话框是最简易的窗口,如果还在Glade中创建的话,很麻烦且会使Glade文件变得更大。下面这些函数,可以快速创建一个窗口而不需要Glade。
- <span style="color:#993333">void</span> gtk_show_info<span style="color:#099000">(</span>gpointer window<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> message<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> title<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkWidget <span style="color:#339933">*</span>dialog<span style="color:#339933">;</span>
- dialog <span style="color:#339933">=</span> gtk_message_dialog_new_with_markup<span style="color:#099000">(</span>window<span style="color:#339933">,</span>
- GTK_DIALOG_DESTROY_WITH_PARENT<span style="color:#339933">,</span>
- GTK_MESSAGE_INFO<span style="color:#339933">,</span>
- GTK_BUTTONS_OK<span style="color:#339933">,</span>
- message<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_window_set_title<span style="color:#099000">(</span>GTK_WINDOW<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">,</span> title<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_dialog_run<span style="color:#099000">(</span>GTK_DIALOG<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_widget_destroy<span style="color:#099000">(</span>GTK_WIDGET<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- <span style="color:#993333">void</span> gtk_show_error<span style="color:#099000">(</span>gpointer window<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> message<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> title<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkWidget <span style="color:#339933">*</span>dialog<span style="color:#339933">;</span>
- dialog <span style="color:#339933">=</span> gtk_message_dialog_new_with_markup<span style="color:#099000">(</span>window<span style="color:#339933">,</span>
- GTK_DIALOG_DESTROY_WITH_PARENT<span style="color:#339933">,</span>
- GTK_MESSAGE_ERROR<span style="color:#339933">,</span>
- GTK_BUTTONS_OK<span style="color:#339933">,</span>
- message<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_window_set_title<span style="color:#099000">(</span>GTK_WINDOW<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">,</span> title<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_dialog_run<span style="color:#099000">(</span>GTK_DIALOG<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_widget_destroy<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- gint gtk_show_question<span style="color:#099000">(</span>gpointer window<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> message<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> title<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- gint i<span style="color:#339933">;</span>
- GtkWidget <span style="color:#339933">*</span>dialog<span style="color:#339933">;</span>
-
- dialog <span style="color:#339933">=</span> gtk_message_dialog_new_with_markup<span style="color:#099000">(</span>window<span style="color:#339933">,</span>
- GTK_DIALOG_DESTROY_WITH_PARENT<span style="color:#339933">,</span>
- GTK_MESSAGE_QUESTION<span style="color:#339933">,</span>
- GTK_BUTTONS_YES_NO<span style="color:#339933">,</span>
- message<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_window_set_title<span style="color:#099000">(</span>GTK_WINDOW<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">,</span> title<span style="color:#099000">)</span><span style="color:#339933">;</span>
- i<span style="color:#339933">=</span>gtk_dialog_run<span style="color:#099000">(</span>GTK_DIALOG<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_widget_destroy<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>i<span style="color:#339933">==</span>GTK_RESPONSE_YES<span style="color:#099000">)</span>
- <span style="color:#b1b100">return</span> <span style="color:#00dd00">1</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">else</span>
- <span style="color:#b1b100">return</span> <span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- <span style="color:#993333">void</span> gtk_show_warning<span style="color:#099000">(</span>gpointer window<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> message<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> title<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkWidget <span style="color:#339933">*</span>dialog<span style="color:#339933">;</span>
- dialog <span style="color:#339933">=</span> gtk_message_dialog_new_with_markup<span style="color:#099000">(</span>window<span style="color:#339933">,</span>
- GTK_DIALOG_DESTROY_WITH_PARENT<span style="color:#339933">,</span>
- GTK_MESSAGE_WARNING<span style="color:#339933">,</span>
- GTK_BUTTONS_OK<span style="color:#339933">,</span>
- message<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_window_set_title<span style="color:#099000">(</span>GTK_WINDOW<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">,</span> title<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_dialog_run<span style="color:#099000">(</span>GTK_DIALOG<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_widget_destroy<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
以上四个函数分别是一个信息窗口、错误提示窗口、询问窗口、警告窗口,三个参数分别是母窗口、窗口内文字内容、窗口标题。在程序中直接调用函数即可。
文件选择对话框
文件选择对话框同样可以不用Glade创建,而直接调用API方便地创建。下面的函数可以创建文件打开对话框和文件保存对话框。
- GtkWidget<span style="color:#339933">*</span> gtk_show_file_add_filter<span style="color:#099000">(</span>GtkWidget<span style="color:#339933">*</span> dialog<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar <span style="color:#339933">*</span>description<span style="color:#339933">,</span> gchar <span style="color:#339933">*</span>pattern<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkWidget <span style="color:#339933">*</span>filter<span style="color:#339933">;</span>
- filter<span style="color:#339933">=</span>GTK_WIDGET<span style="color:#099000">(</span>gtk_file_filter_new<span style="color:#099000">(</span><span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_file_filter_set_name<span style="color:#099000">(</span>GTK_FILE_FILTER<span style="color:#099000">(</span>filter<span style="color:#099000">)</span><span style="color:#339933">,</span>description<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_file_filter_add_pattern<span style="color:#099000">(</span>GTK_FILE_FILTER<span style="color:#099000">(</span>filter<span style="color:#099000">)</span><span style="color:#339933">,</span>pattern<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_file_chooser_add_filter<span style="color:#099000">(</span>GTK_FILE_CHOOSER<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">,</span>GTK_FILE_FILTER<span style="color:#099000">(</span>filter<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">return</span> filter<span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- gchar<span style="color:#339933">*</span> gtk_show_file_open<span style="color:#099000">(</span>GtkWidget<span style="color:#339933">*</span> parent_window<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar <span style="color:#339933">*</span>title<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar <span style="color:#339933">*</span>filters<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkWidget <span style="color:#339933">*</span>dialog<span style="color:#339933">,*</span>FF<span style="color:#099000">[</span><span style="color:#00dd00">16</span><span style="color:#099000">]</span><span style="color:#339933">;</span>
- gchar <span style="color:#339933">*</span>filename<span style="color:#339933">,</span>des<span style="color:#099000">[</span><span style="color:#00dd00">256</span><span style="color:#099000">]</span><span style="color:#339933">,</span>pattern<span style="color:#099000">[</span><span style="color:#00dd00">64</span><span style="color:#099000">]</span><span style="color:#339933">;</span>
- <span style="color:#993333">long</span> i<span style="color:#339933">,</span>j<span style="color:#339933">,</span>FFc<span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>
-
- dialog <span style="color:#339933">=</span> gtk_file_chooser_dialog_new <span style="color:#099000">(</span>title<span style="color:#339933">,</span>
- GTK_WINDOW<span style="color:#099000">(</span>parent_window<span style="color:#099000">)</span><span style="color:#339933">,</span>
- GTK_FILE_CHOOSER_ACTION_OPEN<span style="color:#339933">,</span>
- <span style="color:#808080; font-style:italic"></span>
- GTK_STOCK_OPEN<span style="color:#339933">,</span> GTK_RESPONSE_ACCEPT<span style="color:#339933">,</span>
- NULL<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
- <span style="color:#b1b100">for</span><span style="color:#099000">(</span>i<span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>i<span style="color:#339933"><</span>strlen<span style="color:#099000">(</span>filters<span style="color:#099000">)</span><span style="color:#339933">;</span>i<span style="color:#339933">++</span><span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- j<span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">while</span><span style="color:#099000">(</span>i<span style="color:#339933"><</span>strlen<span style="color:#099000">(</span>filters<span style="color:#099000">)</span> <span style="color:#339933">&&</span> filters<span style="color:#099000">[</span>i<span style="color:#099000">]</span><span style="color:#339933">!=</span><span style="color:#ff0000">'|'</span><span style="color:#099000">)</span>
- des<span style="color:#099000">[</span>j<span style="color:#339933">++</span><span style="color:#099000">]</span><span style="color:#339933">=</span>filters<span style="color:#099000">[</span>i<span style="color:#339933">++</span><span style="color:#099000">]</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>j<span style="color:#339933">>=</span><span style="color:#00dd00">256</span><span style="color:#099000">)</span><span style="color:#000000; font-weight:bold">break</span><span style="color:#339933">;</span>
- des<span style="color:#099000">[</span>j<span style="color:#099000">]</span><span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- j<span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- i<span style="color:#339933">++;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>i<span style="color:#339933">>=</span>strlen<span style="color:#099000">(</span>filters<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#000000; font-weight:bold">break</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">while</span><span style="color:#099000">(</span>i<span style="color:#339933"><</span>strlen<span style="color:#099000">(</span>filters<span style="color:#099000">)</span> <span style="color:#339933">&&</span> filters<span style="color:#099000">[</span>i<span style="color:#099000">]</span><span style="color:#339933">!=</span><span style="color:#ff0000">'|'</span><span style="color:#099000">)</span>
- pattern<span style="color:#099000">[</span>j<span style="color:#339933">++</span><span style="color:#099000">]</span><span style="color:#339933">=</span>filters<span style="color:#099000">[</span>i<span style="color:#339933">++</span><span style="color:#099000">]</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>j<span style="color:#339933">>=</span><span style="color:#00dd00">64</span><span style="color:#099000">)</span><span style="color:#000000; font-weight:bold">break</span><span style="color:#339933">;</span>
- pattern<span style="color:#099000">[</span>j<span style="color:#099000">]</span><span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- FF<span style="color:#099000">[</span>FFc<span style="color:#339933">++</span><span style="color:#099000">]</span><span style="color:#339933">=</span>gtk_show_file_add_filter<span style="color:#099000">(</span>dialog<span style="color:#339933">,</span>des<span style="color:#339933">,</span>pattern<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>FFc<span style="color:#339933">>=</span><span style="color:#00dd00">16</span><span style="color:#099000">)</span><span style="color:#000000; font-weight:bold">break</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- <span style="color:#b1b100">if</span> <span style="color:#099000">(</span>gtk_dialog_run <span style="color:#099000">(</span>GTK_DIALOG <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span> <span style="color:#339933">==</span> GTK_RESPONSE_ACCEPT<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- filename <span style="color:#339933">=</span> gtk_file_chooser_get_filename <span style="color:#099000">(</span>GTK_FILE_CHOOSER <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_object_destroy<span style="color:#099000">(</span>GTK_OBJECT<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">return</span> filename<span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- <span style="color:#b1b100">return</span> NULL<span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- gchar<span style="color:#339933">*</span> gtk_show_file_save<span style="color:#099000">(</span>GtkWidget<span style="color:#339933">*</span> parent_window<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar <span style="color:#339933">*</span>title<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar <span style="color:#339933">*</span>default_folder<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar <span style="color:#339933">*</span>default_name<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar <span style="color:#339933">*</span>filters<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkWidget <span style="color:#339933">*</span>dialog<span style="color:#339933">,*</span>FF<span style="color:#099000">[</span><span style="color:#00dd00">16</span><span style="color:#099000">]</span><span style="color:#339933">;</span>
- gchar <span style="color:#339933">*</span>filename<span style="color:#339933">,</span>des<span style="color:#099000">[</span><span style="color:#00dd00">256</span><span style="color:#099000">]</span><span style="color:#339933">,</span>pattern<span style="color:#099000">[</span><span style="color:#00dd00">64</span><span style="color:#099000">]</span><span style="color:#339933">;</span>
- <span style="color:#993333">long</span> i<span style="color:#339933">,</span>j<span style="color:#339933">,</span>FFc<span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>
-
- dialog <span style="color:#339933">=</span> gtk_file_chooser_dialog_new <span style="color:#099000">(</span>title<span style="color:#339933">,</span>
- GTK_WINDOW<span style="color:#099000">(</span>parent_window<span style="color:#099000">)</span><span style="color:#339933">,</span>
- GTK_FILE_CHOOSER_ACTION_SAVE<span style="color:#339933">,</span>
- <span style="color:#808080; font-style:italic"></span>
- GTK_STOCK_SAVE<span style="color:#339933">,</span> GTK_RESPONSE_ACCEPT<span style="color:#339933">,</span>
- NULL<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_file_chooser_set_do_overwrite_confirmation <span style="color:#099000">(</span>GTK_FILE_CHOOSER <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">,</span> TRUE<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>default_folder<span style="color:#099000">[</span><span style="color:#00dd00">0</span><span style="color:#099000">]</span><span style="color:#339933">!=</span><span style="color:#00dd00">0</span><span style="color:#099000">)</span>gtk_file_chooser_set_current_folder <span style="color:#099000">(</span>GTK_FILE_CHOOSER <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">,</span> default_folder<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_file_chooser_set_current_name <span style="color:#099000">(</span>GTK_FILE_CHOOSER <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">,</span> default_name<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
- <span style="color:#b1b100">for</span><span style="color:#099000">(</span>i<span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>i<span style="color:#339933"><</span>strlen<span style="color:#099000">(</span>filters<span style="color:#099000">)</span><span style="color:#339933">;</span>i<span style="color:#339933">++</span><span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- j<span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">while</span><span style="color:#099000">(</span>i<span style="color:#339933"><</span>strlen<span style="color:#099000">(</span>filters<span style="color:#099000">)</span> <span style="color:#339933">&&</span> filters<span style="color:#099000">[</span>i<span style="color:#099000">]</span><span style="color:#339933">!=</span><span style="color:#ff0000">'|'</span><span style="color:#099000">)</span>
- des<span style="color:#099000">[</span>j<span style="color:#339933">++</span><span style="color:#099000">]</span><span style="color:#339933">=</span>filters<span style="color:#099000">[</span>i<span style="color:#339933">++</span><span style="color:#099000">]</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>j<span style="color:#339933">>=</span><span style="color:#00dd00">256</span><span style="color:#099000">)</span><span style="color:#000000; font-weight:bold">break</span><span style="color:#339933">;</span>
- des<span style="color:#099000">[</span>j<span style="color:#099000">]</span><span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- j<span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- i<span style="color:#339933">++;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>i<span style="color:#339933">>=</span>strlen<span style="color:#099000">(</span>filters<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#000000; font-weight:bold">break</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">while</span><span style="color:#099000">(</span>i<span style="color:#339933"><</span>strlen<span style="color:#099000">(</span>filters<span style="color:#099000">)</span> <span style="color:#339933">&&</span> filters<span style="color:#099000">[</span>i<span style="color:#099000">]</span><span style="color:#339933">!=</span><span style="color:#ff0000">'|'</span><span style="color:#099000">)</span>
- pattern<span style="color:#099000">[</span>j<span style="color:#339933">++</span><span style="color:#099000">]</span><span style="color:#339933">=</span>filters<span style="color:#099000">[</span>i<span style="color:#339933">++</span><span style="color:#099000">]</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>j<span style="color:#339933">>=</span><span style="color:#00dd00">64</span><span style="color:#099000">)</span><span style="color:#000000; font-weight:bold">break</span><span style="color:#339933">;</span>
- pattern<span style="color:#099000">[</span>j<span style="color:#099000">]</span><span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- FF<span style="color:#099000">[</span>FFc<span style="color:#339933">++</span><span style="color:#099000">]</span><span style="color:#339933">=</span>gtk_show_file_add_filter<span style="color:#099000">(</span>dialog<span style="color:#339933">,</span>des<span style="color:#339933">,</span>pattern<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>FFc<span style="color:#339933">>=</span><span style="color:#00dd00">16</span><span style="color:#099000">)</span><span style="color:#000000; font-weight:bold">break</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- <span style="color:#b1b100">if</span> <span style="color:#099000">(</span>gtk_dialog_run <span style="color:#099000">(</span>GTK_DIALOG <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span> <span style="color:#339933">==</span> GTK_RESPONSE_ACCEPT<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- filename <span style="color:#339933">=</span> gtk_file_chooser_get_filename <span style="color:#099000">(</span>GTK_FILE_CHOOSER <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_widget_destroy <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">return</span> filename<span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- <span style="color:#666666; font-style:italic">
- gtk_widget_destroy <span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">for</span><span style="color:#099000">(</span>i<span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>i<span style="color:#339933"><</span>FFc<span style="color:#339933">;</span>i<span style="color:#339933">++</span><span style="color:#099000">)</span>
- gtk_object_destroy<span style="color:#099000">(</span>GTK_OBJECT<span style="color:#099000">(</span>FF<span style="color:#099000">[</span>i<span style="color:#099000">]</span><span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#b1b100">return</span> NULL<span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
gtk_show_file_open()建立一个文件打开窗口供用户选择文件,参数依次是母窗口、标题、过滤器。
gtk_show_file_save()建立一个文件保存窗口供用户选择文件,参数依次是母窗口、标题、默认文件夹、默认文件名、过滤器。
其中“过滤器”是一串字符,字符内用“|”分离,其形式像这样:文件类型名称1|对应通配符1|文件类型名称2|对应通配符2|……
使用GDK函数
GTK+提供好了丰富的功能,但也有缺陷——某些常用功能无法直接使用,需要访问GDK库。下面这个函数,用来确定窗口是不是处于全屏状态。
- gboolean gtk_window_is_fullscreen<span style="color:#099000">(</span>GtkWindow<span style="color:#339933">*</span> window<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- <span style="color:#b1b100">return</span> <span style="color:#099000">(</span>gdk_window_get_state<span style="color:#099000">(</span>gtk_widget_get_window<span style="color:#099000">(</span>GTK_WIDGET<span style="color:#099000">(</span>window<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#099000">)</span> <span style="color:#339933">&</span> GDK_WINDOW_STATE_FULLSCREEN<span style="color:#099000">)</span> <span style="color:#339933">==</span> GDK_WINDOW_STATE_FULLSCREEN<span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
其他用法,请参阅GTK+参考。
原文地址:http://blog.programet.org/2010/10/gtk-5.html
这一部分内容介绍有关GTK+常用文本类物件的一些函数。如果对内容有疑问,请在下方留言,谢谢!
GTK+的文本
显示文字和控制文本框自然是界面重头戏,基本每个窗口都离不开这样的物件。GTK+中和文本有关的物件主要有:文本标签(GtkLabel,以下简称“文本”),输入框(GtkEntry),可编辑多行文本(GtkTextView,以下简称“多行文本”),调节按钮(GtkSpinButton)。各物件有自己的优点。
- 文本:简单地显示一些文字,使用非常方便,一般用于显示界面上最普通的文字。
- 输入框:用于让用户输入一行文字,使用方便。
- 多行文本:用于让用户输入多行文字,或显示一段非常长的文字,可配合滚动区(GtkScrolledWindow)使用来达到很好的显示效果,也可为部分文字设置样式。它的缺陷在于使用繁琐。
- 调节按钮:用于输入数字,在控制数字输入方面的功能非常强大,其右侧有上下调节数字大小的按钮。
具体使用哪个物件需要根据实际情况决定。
访问文本、输入框
对文本类物件的操作基本相似。对这些物件的动态访问基本归结为以下两种——读取所包含的文字信息(读)、设置所包含的文字内容(写)。其他的设置基本不需要动态改变,初始时在Glade中设置好即可(如果真的需要修改,自己去看参考吧)。
下面这些函数用于对文本、输入框的读写,函数名字都很好记。
- <span style="color:#666666; font-style:italic">
- <span style="color:#993333">void</span> gtk_label_set_text<span style="color:#099000">(</span>GtkLabel <span style="color:#339933">*</span>label<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar <span style="color:#339933">*</span>str<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#666666; font-style:italic">
- <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> gtk_label_get_text<span style="color:#099000">(</span>GtkLabel <span style="color:#339933">*</span>label<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#666666; font-style:italic">
- <span style="color:#993333">void</span> gtk_entry_set_text<span style="color:#099000">(</span>GtkEntry <span style="color:#339933">*</span>entry<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar <span style="color:#339933">*</span>text<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#666666; font-style:italic">
- <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> gtk_entry_get_text<span style="color:#099000">(</span>GtkEntry <span style="color:#339933">*</span>entry<span style="color:#099000">)</span><span style="color:#339933">;</span>
|
使用调节按钮
调节按钮是用于操作数字的,因而可以直接向其中写入或者读出实数或整数。
- <span style="color:#666666; font-style:italic">
- <span style="color:#993333">void</span> gtk_spin_button_set_value <span style="color:#099000">(</span>GtkSpinButton <span style="color:#339933">*</span>spin_button<span style="color:#339933">,</span> gdouble value<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#666666; font-style:italic">
- gdouble gtk_spin_button_get_value <span style="color:#099000">(</span>GtkSpinButton <span style="color:#339933">*</span>spin_button<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gint gtk_spin_button_get_value_as_int<span style="color:#099000">(</span>GtkSpinButton <span style="color:#339933">*</span>spin_button<span style="color:#099000">)</span><span style="color:#339933">;</span>
|
做个实例吧。本系列第三部分做了一个计算器雏形,下面来稍稍完善一下。
计算器的上方有一个名为SAns的调节按钮,下面增加一个功能:当调节按钮的值的绝对值过大(大于等于常数CAL_ABS_MAX)时,弹出错误提示窗口。
每个调节按钮对应一个GtkAdjustment,首先应为调节按钮添加一个GtkAdjustment。在Glade中,点“常规”的“调整部件”右侧的“…”,弹出窗口中点“New”。
此时上方的物件选择栏末尾中会出现一个对象adjustment1,可以更改它的属性,即调节按钮的最值、步长等。
然后为SAns的信号value-changed添加操作句柄“on_SAns_value_changed”,然后在程序中添加相应回调函数。
回到程序中,在初始化时,用gtk_spin_button_set_range()修改调节按钮取值范围为[-CAL_ABS_MAX,CAL_ABS_MAX],再编写回调函数on_SAns_value_changed(),顺便用上上一部分写的函数gtk_show_error()。完整代码如下。
- <span style="color:#339933">#include <gtk/gtk.h></span>
-
- <span style="color:#339933">#define CAL_ABS_MAX 1e9</span>
-
- <span style="color:#339933">#define w_(builder,type,name) name=GTK_##type(gtk_builder_get_object(builder,#name))</span>
-
- GtkWindow <span style="color:#339933">*</span>WMain<span style="color:#339933">;</span>
- GtkSpinButton <span style="color:#339933">*</span>SAns<span style="color:#339933">;</span>
-
- <span style="color:#666666; font-style:italic">
- <span style="color:#993333">void</span> gtk_show_error<span style="color:#099000">(</span>gpointer window<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> message<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> title<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkWidget <span style="color:#339933">*</span>dialog<span style="color:#339933">;</span>
- dialog <span style="color:#339933">=</span> gtk_message_dialog_new_with_markup<span style="color:#099000">(</span>window<span style="color:#339933">,</span>
- GTK_DIALOG_DESTROY_WITH_PARENT<span style="color:#339933">,</span>
- GTK_MESSAGE_ERROR<span style="color:#339933">,</span>
- GTK_BUTTONS_OK<span style="color:#339933">,</span>
- message<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_window_set_title<span style="color:#099000">(</span>GTK_WINDOW<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">,</span> title<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_dialog_run<span style="color:#099000">(</span>GTK_DIALOG<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_widget_destroy<span style="color:#099000">(</span>dialog<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- G_MODULE_EXPORT <span style="color:#993333">void</span> on_SAns_value_changed<span style="color:#099000">(</span>GtkObject<span style="color:#339933">*</span> widget<span style="color:#339933">,</span> gpointer user_data<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- <span style="color:#666666; font-style:italic">
- gdouble d<span style="color:#339933">;</span>
- <span style="color:#666666; font-style:italic">
- d<span style="color:#339933">=</span>gtk_spin_button_get_value<span style="color:#099000">(</span>SAns<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#666666; font-style:italic">
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>d<span style="color:#339933">>=</span>CAL_ABS_MAX<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- gtk_show_error<span style="color:#099000">(</span>WMain<span style="color:#339933">,</span><span style="color:#ff0000">"Too Large"</span><span style="color:#339933">,</span><span style="color:#ff0000">"Error!"</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#666666; font-style:italic">
- gtk_spin_button_set_value<span style="color:#099000">(</span>SAns<span style="color:#339933">,</span><span style="color:#00dd00">0</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
- <span style="color:#b1b100">else</span> <span style="color:#b1b100">if</span><span style="color:#099000">(</span><span style="color:#339933">-</span>d<span style="color:#339933">>=</span>CAL_ABS_MAX<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- gtk_show_error<span style="color:#099000">(</span>WMain<span style="color:#339933">,</span><span style="color:#ff0000">"Too Small"</span><span style="color:#339933">,</span><span style="color:#ff0000">"Error!"</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#666666; font-style:italic">
- gtk_spin_button_set_value<span style="color:#099000">(</span>SAns<span style="color:#339933">,</span><span style="color:#00dd00">0</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
- <span style="color:#099000">}</span>
-
- G_MODULE_EXPORT <span style="color:#993333">void</span> on_WMain_destroy<span style="color:#099000">(</span>GtkObject<span style="color:#339933">*</span> widget<span style="color:#339933">,</span> gpointer user_data<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- gtk_main_quit<span style="color:#099000">(</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- GtkBuilder<span style="color:#339933">*</span> gtk_load_glade<span style="color:#099000">(</span>gchar<span style="color:#339933">*</span> filename<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkBuilder <span style="color:#339933">*</span>gb<span style="color:#339933">;</span>
-
- gb<span style="color:#339933">=</span>gtk_builder_new<span style="color:#099000">(</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span><span style="color:#339933">!</span>gtk_builder_add_from_file<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>filename<span style="color:#339933">,</span>NULL<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#b1b100">return</span> NULL<span style="color:#339933">;</span>
- gtk_builder_connect_signals<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>NULL<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#b1b100">return</span> gb<span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- <span style="color:#993333">void</span> cal_get_widgets<span style="color:#099000">(</span>GtkBuilder<span style="color:#339933">*</span> gb<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- w_<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>WINDOW<span style="color:#339933">,</span>WMain<span style="color:#099000">)</span><span style="color:#339933">;</span>
- w_<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>SPIN_BUTTON<span style="color:#339933">,</span>SAns<span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- <span style="color:#993333">void</span> cal_widget_init<span style="color:#099000">(</span><span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- <span style="color:#666666; font-style:italic">
- gtk_spin_button_set_range<span style="color:#099000">(</span>SAns<span style="color:#339933">,-</span>CAL_ABS_MAX<span style="color:#339933">,</span>CAL_ABS_MAX<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- gtk_widget_show_all<span style="color:#099000">(</span>GTK_WIDGET<span style="color:#099000">(</span>WMain<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
-
- <span style="color:#993333">int</span> main<span style="color:#099000">(</span><span style="color:#993333">int</span> argc<span style="color:#339933">,</span> <span style="color:#993333">char</span> <span style="color:#339933">*</span>argv<span style="color:#099000">[</span><span style="color:#099000">]</span><span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkBuilder <span style="color:#339933">*</span>gb<span style="color:#339933">;</span>
-
- gtk_init<span style="color:#099000">(</span><span style="color:#339933">&</span>argc<span style="color:#339933">,&</span>argv<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- gb<span style="color:#339933">=</span>gtk_load_glade<span style="color:#099000">(</span><span style="color:#ff0000">"gtk-cal.glade"</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">if</span><span style="color:#099000">(</span>gb<span style="color:#339933">==</span>NULL<span style="color:#099000">)</span><span style="color:#b1b100">return</span> <span style="color:#339933">-</span><span style="color:#00dd00">1</span><span style="color:#339933">;</span>
- cal_get_widgets<span style="color:#099000">(</span>gb<span style="color:#099000">)</span><span style="color:#339933">;</span>
- cal_widget_init<span style="color:#099000">(</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- gtk_main<span style="color:#099000">(</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- <span style="color:#b1b100">return</span> <span style="color:#00dd00">0</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
在以后的内容中,这个计算器将被逐渐完善。
访问多行文本
多行文本的使用比较复杂,涉及几个其他对象的使用。一个多行文本的内容储存在一个缓冲区GtkTextBuffer中,这个缓冲区需要用迭代器GtkTextIter访问、用GtkTextMark标记,文字样式用GtkTextTag设置。
看起来真的有些复杂。不过最基本的应用还是读、写。下面给出三个函数,可以直接读写多行文本。这几个函数基本够用了。
- <span style="color:#666666; font-style:italic">
- gchar<span style="color:#339933">*</span> gtk_text_view_get<span style="color:#099000">(</span>GtkTextView <span style="color:#339933">*</span>text_view<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkTextBuffer <span style="color:#339933">*</span>tb<span style="color:#339933">;</span>
- GtkTextIter st<span style="color:#339933">,</span>stp<span style="color:#339933">;</span>
-
- tb<span style="color:#339933">=</span>gtk_text_view_get_buffer<span style="color:#099000">(</span>text_view<span style="color:#099000">)</span><span style="color:#339933">;</span> <span style="color:#666666; font-style:italic">
- gtk_text_buffer_get_start_iter<span style="color:#099000">(</span>tb<span style="color:#339933">,&</span>st<span style="color:#099000">)</span><span style="color:#339933">;</span> <span style="color:#666666; font-style:italic">
- gtk_text_buffer_get_end_iter<span style="color:#099000">(</span>tb<span style="color:#339933">,&</span>stp<span style="color:#099000">)</span><span style="color:#339933">;</span> <span style="color:#666666; font-style:italic">
- <span style="color:#b1b100">return</span> gtk_text_buffer_get_text<span style="color:#099000">(</span>tb<span style="color:#339933">,&</span>st<span style="color:#339933">,&</span>stp<span style="color:#339933">,</span>FALSE<span style="color:#099000">)</span><span style="color:#339933">;</span> <span style="color:#666666; font-style:italic">
- <span style="color:#099000">}</span>
- <span style="color:#666666; font-style:italic">
- <span style="color:#993333">void</span> gtk_text_view_append_with_tag<span style="color:#099000">(</span>GtkTextView<span style="color:#339933">*</span> text_view<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar<span style="color:#339933">*</span> text<span style="color:#339933">,</span> GtkTextTag<span style="color:#339933">*</span> text_tag<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- GtkTextBuffer <span style="color:#339933">*</span>tb<span style="color:#339933">;</span>
- GtkTextIter stp<span style="color:#339933">;</span>
-
- tb<span style="color:#339933">=</span>gtk_text_view_get_buffer<span style="color:#099000">(</span>text_view<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_text_buffer_get_end_iter<span style="color:#099000">(</span>tb<span style="color:#339933">,&</span>stp<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_text_buffer_insert_with_tags<span style="color:#099000">(</span>tb<span style="color:#339933">,&</span>stp<span style="color:#339933">,</span>text<span style="color:#339933">,</span>strlen<span style="color:#099000">(</span>text<span style="color:#099000">)</span><span style="color:#339933">,</span>text_tag<span style="color:#339933">,</span>NULL<span style="color:#099000">)</span><span style="color:#339933">;</span> <span style="color:#666666; font-style:italic">
- gtk_text_buffer_get_end_iter<span style="color:#099000">(</span>tb<span style="color:#339933">,&</span>stp<span style="color:#099000">)</span><span style="color:#339933">;</span>
- gtk_text_view_scroll_to_iter<span style="color:#099000">(</span>text_view<span style="color:#339933">,&</span>stp<span style="color:#339933">,</span><span style="color:#00dd00">0</span><span style="color:#339933">,</span>FALSE<span style="color:#339933">,</span><span style="color:#00dd00">0</span><span style="color:#339933">,</span><span style="color:#00dd00">0</span><span style="color:#099000">)</span><span style="color:#339933">;</span> <span style="color:#666666; font-style:italic">
- <span style="color:#099000">}</span>
- <span style="color:#666666; font-style:italic">
- <span style="color:#993333">void</span> gtk_text_view_clear<span style="color:#099000">(</span>GtkTextView <span style="color:#339933">*</span>text_view<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- gtk_text_buffer_set_text<span style="color:#099000">(</span>gtk_text_view_get_buffer<span style="color:#099000">(</span>text_view<span style="color:#099000">)</span><span style="color:#339933">,</span><span style="color:#ff0000">""</span><span style="color:#339933">,</span><span style="color:#00dd00">0</span><span style="color:#099000">)</span><span style="color:#339933">;</span> <span style="color:#666666; font-style:italic">
- <span style="color:#099000">}</span>
|
此外,样式可以这样新建:
- gtk_text_buffer_create_tag<span style="color:#099000">(</span>gtk_text_view_get_buffer<span style="color:#099000">(</span>text_view<span style="color:#099000">)</span><span style="color:#339933">,</span> tag_name<span style="color:#339933">,</span> property1<span style="color:#339933">,</span> value1<span style="color:#339933">,</span> property2<span style="color:#339933">,</span> value2<span style="color:#339933">,</span> ... <span style="color:#339933">,</span> NULL<span style="color:#099000">)</span><span style="color:#339933">;</span>
|
text_view是多行文本名字;tag_name是一个字符串,值不能和别的样式相同;property1,2,3,…各属性名字(字符串形式),可用的属性参见http://library.gnome.org/devel/gtk/unstable/GtkTextTag.html中的Property栏;value1,2,3,…各属性对应的值(字符串形式)。
如果以上的方法不够用,只好查参考了。
小提醒:多行文本一般都需要放在滚动区(GtkScrolledWindow)里面。
处理UTF-8字符串
要注意的问题是,GTK+内部使用UTF-8编码。在处理非ASCII编码的字符串时,切不可使用C语言string.h里的函数。在UTF-8中,字符含义比较复杂。还好,GLib中提供了很多用于处理多种编码字符串的函数,下面介绍一些用于处理UTF-8字符串的函数。
在http://library.gnome.org/devel/glib/stable/glib-Unicode-Manipulation.html中介绍了很多有关UTF-8字符串的实用函数。这些函数命名与string.h里的常用函数相近,只是多了前缀g_utf8_,表示是专门用来处理UTF-8字符串的。介绍几个吧。
- g_utf8_strlen():统计UTF-8字符串中的字符数。在UTF-8编码中,不同语言的字符所占用的字节数不同(例如一个中文字符占3个字节),因而UTF-8所包含的字符数小于等于它的字节数,并且没有一个固定的关系。这个函数还是很常用且重要的。
- g_utf8_find_prev_char():已知某个字符的首地址,查找它前一个字符的首地址。因为不同语言的字符所占用的字节数不同,两个紧邻字符地址之差可能大于1。
- g_utf8_find_next_char():已知某个字符的首地址,查找它后一个字符的首地址。
- g_utf8_strncpy():拷贝出字符串的前n个字符(而不是前n个字节)。
- g_utf8_strchr():找到一个给定的字符最左端出现的位置。UTF-8字符串中字符是gunichar型,相当于一个32位无符号整数,对于非ASCII字符,其值大于127。
- g_utf8_collate():比较两个字符串的大小(以字典序靠前的为小)。这个函数的强大之处在于,它可以根据所处的语言环境来判断两个字符串的字典顺序,可以比较任何语言的UTF-8字符串!
在http://library.gnome.org/devel/glib/stable/glib-String-Utility-Functions.html列出了一些跨字符集的实用函数,适用于任何字符集。其中有一部分常常能用上,比如g_snprintf()和g_strdup_printf(),它们的功能与C语言sprintf类似,都是把一串格式输出写进字符串里(常用于数字和字符混合输出到字符串里),但g_snprintf()和g_strdup_printf()更安全。g_snprintf()需要指定目的字符串长度,避免输出越界;g_strdup_printf()则在函数内部自行申请足够的空间存放目的字符串(注意它返回的字符串废弃之后需要用g_free()释放空间)。
在http://library.gnome.org/devel/glib/stable/glib-Character-Set-Conversion.html有一些字符集转换的函数,有些需要字符集转换的场合会用得上(比如文件名可能不是UTF-8编码,有时需要转换)。
原文地址:http://blog.programet.org/2011/03/gtk-6.html
这一部分内容介绍有关GTK+常用按钮、选择框物件的一些函数,以及相关的使用技巧。如果对内容有疑问,请在下方留言,谢谢!
GTK+的各种按钮和选择框
GTK+提供了各种各样的按钮,功能丰富,能满足各种不同的需求。按钮可大致分为下面几种:
- 普通按钮(GtkButton)、链接按钮(GtkLinkButton):最常用也最简单,唯一的操作是按一下。
- 复选框(GtkCheckButton)、双态按钮(GtkToggleButton):这两种按钮本质是一致的,按钮有两个状态(按下和弹起)。
- 单选框(GtkRadioButton)、下拉菜单(GtkComboBox):可以从多个项目中选择一个。
- 文件选择按钮(GtkFileChooserButton)、颜色选择按钮(GtkColorButton)、字体选择按钮(GtkFontButton):这些按钮按下后会弹出对话框,供用户选择。
- 菜单和与菜单相关的物件:用于构建菜单、工具栏等。
此外还有一些别的按钮,可以提供丰富的细节功能。想用的话请自行查参考。
Glade对它们提供了很好的支持。尤其是提供了菜单编辑器,菜单完全不用写代码构建,这提供了很大的方便。对于可以在Glade中完成的部分,这里不再多做介绍。
信号
按钮和选择框在运行时较少被动态更改,使用这些物件最主要的还是获取信号执行操作。在第三部分的末尾已经介绍了链接信号的基本方法:在Glade中想要连接的信号,输入回调函数名,在程序中编写回调函数。
对于普通按钮,“clicked”肯定是最常用的一个信号。而对于复选框和双态按钮,应当使用“toggled”信号,不建议使用其他信号代替。因为在这个信号被触发时,按钮的状态已经被改变了,可以立即使用gtk_toggle_button_get_active()函数获得按钮的最新状态。
技巧:建立物件数组
有时,按钮在一起时比较便于管理,因而时常会把物件放入数组中管理。这需要在获取物件地址时把物件地址存入数组中。聪明的做法是,在Glade中命名物件时起有规律的名字。
下面继续编写计算器程序来展示这种手段。
计算器的0~9这10个按钮操作是类似的,因而可以放在数组中管理。首先为按钮起类似的名字:BNum0,BNum1,BNum2,…,BNum9。获取物件的函数原型如下:
- GObject<span style="color:#339933">*</span> gtk_builder_get_object<span style="color:#099000">(</span>GtkBuilder <span style="color:#339933">*</span>builder<span style="color:#339933">,</span> <span style="color:#993333">const</span> gchar <span style="color:#339933">*</span>name<span style="color:#099000">)</span><span style="color:#339933">;</span>
|
因而可以用这段代码把物件放入一个数组中:
- GtkButton <span style="color:#339933">*</span>BNum<span style="color:#099000">[</span><span style="color:#00dd00">10</span><span style="color:#099000">]</span><span style="color:#339933">;</span>
- gint i<span style="color:#339933">;</span>
- gchar s<span style="color:#099000">[</span><span style="color:#00dd00">6</span><span style="color:#099000">]</span><span style="color:#339933">;</span>
- strcpy<span style="color:#099000">(</span>s<span style="color:#339933">,</span><span style="color:#ff0000">"BNum_"</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">for</span><span style="color:#099000">(</span>i<span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>i<span style="color:#339933"><</span><span style="color:#00dd00">10</span><span style="color:#339933">;</span>i<span style="color:#339933">++</span><span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- s<span style="color:#099000">[</span><span style="color:#00dd00">4</span><span style="color:#099000">]</span><span style="color:#339933">=</span>i<span style="color:#339933">+</span><span style="color:#ff0000">'0'</span><span style="color:#339933">;</span>
- BNum<span style="color:#099000">[</span>i<span style="color:#099000">]</span><span style="color:#339933">=</span>GTK_BUTTON<span style="color:#099000">(</span>gtk_builder_get_object<span style="color:#099000">(</span>builder<span style="color:#339933">,</span>s<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
|
小提示:如果物件超过了10个,可以使用sprintf()或者glib中的g_strdup_printf()来得到等同于物件名的字符串。在Glade中复制物件,物件的名字会自动按照末尾数字递增命名,并且物件的属性和信号也会一同被复制。
在连接信号时,可以把数组里所有类似的信号连接到同一个函数里。注意:回调函数的第一个参数总是GtkObject* widget,即信号对应物件的地址,可以用这个参数来判断是具体是哪个物件发出了信号。
下面给出最新的获取物件函数。
- <span style="color:#993333">void</span> cal_get_widgets<span style="color:#099000">(</span>GtkBuilder<span style="color:#339933">*</span> gb<span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- gint i<span style="color:#339933">;</span>
- gchar s<span style="color:#099000">[</span><span style="color:#00dd00">6</span><span style="color:#099000">]</span><span style="color:#339933">;</span>
-
- w_<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>WINDOW<span style="color:#339933">,</span>WMain<span style="color:#099000">)</span><span style="color:#339933">;</span>
- w_<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>SPIN_BUTTON<span style="color:#339933">,</span>SAns<span style="color:#099000">)</span><span style="color:#339933">;</span>
- w_<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>BUTTON<span style="color:#339933">,</span>BPoint<span style="color:#099000">)</span><span style="color:#339933">;</span>
- w_<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>BUTTON<span style="color:#339933">,</span>BPlus<span style="color:#099000">)</span><span style="color:#339933">;</span>
- w_<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>BUTTON<span style="color:#339933">,</span>BMinus<span style="color:#099000">)</span><span style="color:#339933">;</span>
- w_<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>BUTTON<span style="color:#339933">,</span>BMulti<span style="color:#099000">)</span><span style="color:#339933">;</span>
- w_<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>BUTTON<span style="color:#339933">,</span>BDiv<span style="color:#099000">)</span><span style="color:#339933">;</span>
-
- strcpy<span style="color:#099000">(</span>s<span style="color:#339933">,</span><span style="color:#ff0000">"BNum_"</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#b1b100">for</span><span style="color:#099000">(</span>i<span style="color:#339933">=</span><span style="color:#00dd00">0</span><span style="color:#339933">;</span>i<span style="color:#339933"><</span><span style="color:#00dd00">10</span><span style="color:#339933">;</span>i<span style="color:#339933">++</span><span style="color:#099000">)</span>
- <span style="color:#099000">{</span>
- s<span style="color:#099000">[</span><span style="color:#00dd00">4</span><span style="color:#099000">]</span><span style="color:#339933">=</span>i<span style="color:#339933">+</span><span style="color:#ff0000">'0'</span><span style="color:#339933">;</span>
- BNum<span style="color:#099000">[</span>i<span style="color:#099000">]</span><span style="color:#339933">=</span>GTK_BUTTON<span style="color:#099000">(</span>gtk_builder_get_object<span style="color:#099000">(</span>gb<span style="color:#339933">,</span>s<span style="color:#099000">)</span><span style="color:#099000">)</span><span style="color:#339933">;</span>
- <span style="color:#099000">}</span>
- <span style="color:#099000">}</span>
|
这个程序将在后面的部分中完成。
快捷键和默认按钮
在Glade中,还可以为每个按钮分配快捷键(加速键)。选定物件后,点击Glade右下角的“公共”选项卡中的“加速键”右侧的“…”按钮,可以在弹出窗口中指定该物件某个信号的快捷键。当窗口处于激活态时按下快捷键,对应的信号会被触发。
GTK+中,每个窗口有一个默认物件,某些情况下会被激活——比如在文本框中输入完毕按下Enter(当然这要将文本框的“激活默认”属性置为TRUE),确认按钮(当然它要被设为默认)会被按下。指定一个按钮为默认物件,需要将“公共”选项卡的“可成为默认”和“默认”都置为TRUE。