展望未来
Mikael Hallendal, 软件工程师, CodeFactory
Richard Hult, 软件工程师, CodeFactory
2002 年 1 月
developerWorks 很高兴地宣布要重新创办 Linux 专区中很受欢迎的
GNOMEnclature专栏。 在这个专栏中,
CodeFactory的 Mikael Hallendal 和 Richard Hult 将向您提供充分利用新的 GNOME 2 平台所需的内部信息。 在这个系列中,您将学习如何使用 GNOME 2 提供的新库和改进后的库, 以使您可以编写自己的 Nautilus 视图、面板 applet 和其它更多东西。在本文中,Mikael 和 Richard 通过浅显易懂地介绍 GTK+ 2(GNOME 2 桌面环境的新基础)来重新开始本系列。到本文的末尾,您将完成编写和编译一些样本 GTK+ 2 程序并且很好地理解了 GTK+ 2 对于 GTK+ 1 的许多改进。
关于本系列 欢迎进入新的 GNOMEnclature专栏!我们正在重新创办本专栏,它包含了全新的内容以帮助您充分使用 GNOME 2 平台。在最初的几篇文章中,我们将讨论 GNOME 2 和 GNOME 1 之间的差异, 以使您掌握最新的 GNOME 知识。这些文章对于想要开始创建 GNOME 应用程序的那些开发人员来说将是一个理想的介绍, 而且对于需要将现有应用程序从 GNOME 1 移植到 GNOME 2 的那些开发人员也有很大帮助。 首先,我们将讨论基础知识。然后,当每个人都充分了解 GNOME 2 的基本原理之后, 我们将提供更深入的知识,向您演示如何充分利用 GNOME 2 平台中的很酷的新库。到本系列的末尾, 您将编写了您自己的 Nautilus 视图、创建了面板 applet 和其它更多东西。 关于本文 因为 GNOME 构建在 GTK+ 之上,开始本系列的最佳方法是描述 GTK+ 1.2 和 GTK+ 2 之间的变化。 因此,在这第一篇文章中,我们将研究 GTK+ 2,并为您提供 GTK+ 2 使用的新的窗口构件(widget)以及 ATK 和 Pango 库的简短描述。在本系列的后面几篇文章中,我们将更深入地研究 GTK+ 2 对象系统以及在本文中涉及的两个新的窗口构件。 介绍 GTK+ 2 在深入研究下一代 GTK+ 之前,您或许想知道什么时候可以指望 GNOME 2 可用于产品。GNOME 2 预定在 2002 年 2 月 15 日发行;如 Gnumeric 和 Evolution 等较大的应用程序将在稍后被移植到 GNOME 2。 好了,让我们开始探讨 GTK+!最初,开发 GTK+ 是为在 Gimp 中使用(GTK 表示 Gimp ToolKit)。GTK+ 目前可在许多平台(包括 Linux 和 Windows)上使用。许多自由的软件项目(包括 GNOME 本身、Mozilla、Gimp 以及许多其它项目)都使用它。 就象 GTK+ 1 一样,GTK+ 2 依赖于 GLib,它是 C 开发者的便利库。GLib 包含许多能使您的编程工作变得更加容易的好功能,包括对象系统和诸如散列表、列表和树之类的数据结构。 GTK+ 2 还依赖于 ATK 和 Pango。ATK 是可访问性工具箱(Accessibility Toolkit),它能使残障人士使用 GTK+ 应用程序。Pango 是显示国际化文本的框架。稍后,本文将描述这两个软件包。 安装 GTK+ 2 要想充分利用本文,我们建议您安装 GTK+ 2 并运行它。要安装 GTK+ 2, 首先应该确保您的系统上安装了 pkg-config 0.8 或更高版本。所有主要的分发版(distribution)都应该有一个提供 pkg-config 的软件包。当然,GTK+ 2 还依赖于外部库,如 glib、atk 和 pango。在 GTK+ 2 编译之前,必须先安装这些库。 通常,最好的方法是先下载最新版本的 glib、atk、pango 和 gtk+ 源代码 tar 压缩包(请参阅本文后面的 参考资料)。 在里面您可以看到最新的“vx.y”目录,当前是“v1.3”。 您可能会感到奇怪:我们花了所有时间都在谈论 GTK+ 2,但还是建议您安装 GTK+ 1.3。 这是因为,在编写本文时,GTK+ 1.3.11 是最新可用的 GTK+ 版本。一旦 GTK+ 完全准备好用于产品时,就会发行 GTK+ 2.0。在此之前,将 GTK+ 1.3 用于测试是没问题的,因为它几乎包括了所有将出现在正式 GTK+ 2.0 发行版中的新功能部件。 好了,既然我们已经解释清楚,就该重新回到安装新的 GTK+ 的话题了。 因为 GTK+ 2 有几个构建时相关性,所以首先应该安装 glib,然后安装 atk、pango 和 gtk+,这个安装次序是很重要的。 如下安装每个软件包: 清单 1. 安装 GTK+ 和支持库源代码
tar xzvf package-version.tar.gz
cd package-version
./configure
make
make install
| 一旦安装完所有软件包,就应该能够启动 gtk-demo , 这是一个很棒的小程序,它使您可以看到 GTK+ 2 在运行。 那么,GTK+ 2 中有哪些新功能呢?许多用户一直要求 GTK+ 具有使用抗锯齿字体的能力。 现在,这一功能部件已被添加到 GTK+ 2。GTK+ 2 字体抗锯齿处理是通过使用 Xft 库和 XRender 扩展(它是 XFree86 4 和更高版本的一部分)实现的。 要使 GTK+ 2 应用程序启用抗锯齿字体,只要设置环境变量 GDK_USE_XFT=1 。 从 GDK_USE_XFT 设置为 1 的 shell 启动的所有 GTK+ 2 应用程序都应该显示抗锯齿字体文本。 如果愿意,请启用抗锯齿文本,然后再次运行 gtk-demo 。 使用抗锯齿字体文本的对话框示例 双倍缓冲和图像处理 字体抗锯齿处理不是 GTK+ 2 中唯一的图形改进;GTK+ 现在使用双倍缓冲来更新屏幕。 由于没有双倍缓冲,所以当重新绘制或调整大小时,GTK+ 1 应用程序有时会闪烁。GTK+ 2 不再有这种问题, 所以新的 GTK+ 2 应用程序的显示将更加平稳。 不仅外观漂亮了许多,GTK+ 2 还根据开发人员的希望提供了许多改进。 例如,GdkPixbuf(以前是一个单独的库)现在是 GTK+ 的一部分。GdkPixbuf 以多种格式(如 GIF、PNG、JPEG、BMP 等等)处理图像的装入和保存。既然 GdkPixbuf 已经是 GTK+ 的一部分了,那么 GTK+ 本身也可以利用它,使用它来绘制菜单、工具栏和按钮的阿尔法混合图标(alpha blended icon)。 这里是装入一个称为 gnome.png 的小位图图像的样本 GTK+ 2 程序: 在样本程序中,我们使用 gtk_image_from_new_file() 函数创建 GtkImage 对象。GtkImage 对象通过内部使用 GdkPixbuf 来自动装入图像: 清单 2. 使用 GtkImage 对象来显示图像
#include <gtk/gtk.h>
int
main (int argc, char **argv)
{
GtkWidget *window;
GtkWidget *image;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (window), "destroy", gtk_main_quit, NULL);
image = gtk_image_new_from_file ("gnome.png");
gtk_container_add (GTK_CONTAINER (window), image);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
| 这里是如何编译这个简单程序:
gcc `pkg-config --cflags --libs gtk+-2.0` -o image-button image-button.c
| 一旦编译完,接着请执行 ./image-button 。这是您应该看到的: Pango Pango 是新的用于国际化文本的布局和显示的全功能框架。 感谢 Pango,GTK+ 2 现在对于那些不居住在美国或欧洲的用户更为有用了。Pango 可以处理以非从左到右方向排列的文本,并且可以容易地管理复杂语言, 甚至还可以处理根据使用环境而采用不同形式的信函。 Pango 支持双向文本,所以您可以将从左到右的文本和从右到左的文本混合编排;还有用于确定各种复杂文本(如阿拉伯语和泰米尔语)形状的插件。Pango 不仅仅是国际化;Pango 库在 Xft 和 XRender 扩展的帮助下处理抗锯齿字体文本的显示。有关更多的详细信息,请阅读两篇有关 Pango 的 developerWorks文章(请参阅 参考资料)。 Unicode 和 UTF-8 在 GTK+ 2 中,传递到 gtk_*() 函数的任何字符串都应该是 Unicode UTF-8 编码形式。 由于内部使用 UTF-8,GTK+ 2 完全消除了 GTK+ 的先前版本中的国际化问题。 因为 ASCII 是 UTF-8 的子集,所以这个更改不会象您想象的那样影响现有的 GTK+ 代码。然而,当 ASCII 直接映射到 UTF-8 后,就不能逆向映射了。许多非英文字符集在以 UTF-8 编码时每个字符占据多个字节。为了处理大于正常字符编码的情况,当需要迭代 UTF-8 字符串形式的字符时, 应该使用称为 g_utf8_next_char() 的特殊函数(实际上,它是一个宏)。 这个宏将根据需要,确定是采用小字节还是大字节“跳跃(hop)”。这里是一个小示例,我们要验证和迭代一个 UTF-8 字符串: 清单 3. 验证和迭代一个 UTF-8 字符串
gchar *p;
g_return_if_fail (g_utf8_validate (str));
p = str;
while (p) {
gunichar c = g_utf8_get_char (p)
/* Do something with c. */
p = g_utf8_next_char (p);
}
| 如果需要将一个本地语言编码的字符串转换成 UTF-8,可以使用: 清单 4. 将本地语言编码的字符串转换成 UTF-8
gchar* g_locale_to_utf8 (const gchar *opsysstring,
gssize length,
gsize *bytes_read,
gsize *bytes_written,
GError **error);
| 如果不想知道读写了多少字节,则最后三个参数可以是 NULL。 如果正在将以 NULL 结束的字符串传递到这个函数,则将长度设置为 -1;例如:
utf8_string = g_locale_to_utf8 (locale_string, -1, NULL, NULL, NULL);
| Atk,可访问性工具箱 现在,GTK+ 2 充分利用 ATK(可访问性工具箱(Accessibility Toolkit))。ATK 使残障人士(如视力低下或行动不便)与 GTK+ 2 应用程序交互成为可能。在今后的文章中, 我们将更详细地讨论 ATK 并向您演示如何使残障人士可以访问您自己的应用程序。 同时,您也可以访问 GNOME“可访问性项目(Accessibility Project)”(请参阅 参考资料)。 固定项(stock item) GNOME 1 和 GNOME 2 都支持“固定项”,使开发人员十分容易地将通用菜单项和按钮添加到他们的应用程序中。 因为固定项是全局定义的,而不是在应用程序内部定义的,所以它们能很容易地为所有 GNOME 应用程序提供统一的外观。 通常,一个单独的固定项由一个图标、一个文本标签和一个可选的快捷键组成。 除了给予应用程序一个统一的外观外,固定项还给国际化提供了很大的帮助, 因为只需要将它们转换一次(在 GTK+ 库中),而没有需要由开发人员自己转换的特定于应用程序的数据。对于 GNOME 2 平台,固定项支持已经从 gnome-lib 移到 GTK+,使更多的应用程序具有一致外观成为可能。 这里的示例代码片段用于创建一个具有软盘图像和“Save”标签的按钮: 清单 5. 创建一个具有软盘图像和“Save”标签的按钮
GtkWidget *button;
button = gtk_button_new_from_stock (GTK_STOCK_SAVE);
| 这里的屏幕快照显示了一个使用四个固定项的工具栏: 使用四个固定项的工具栏 在菜单项中也可以使用固定项,如下所示: 清单 6. 创建一个具有软盘图像和“Save”标签的菜单项
GtkWidget *menu_item;
menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE);
| 此代码创建一个具有软盘图像和“Save”标签的菜单项。它还将 Ctrl+S 键盘快捷键自动连接到该菜单项。 无论您正巧在使用什么应用程序,使用固定项可确保 Ctrl-S 将始终是缺省的保存快捷键。 如果有合适的固定项可供使用,那么强烈建议您利用它来创建菜单项、工具栏和按钮。 这样,不仅可以使用户界面变得更加一致,而且还节省了宝贵的时间和代码行。 您还可以在自己的应用程序中本地创建固定项。 如果需要在几个地方使用这些项,那么这样可以节省时间和代码,而且它还可以为图标加上标题。 标记 通过 GTK+ 2,在指定文本窗口构件时使用不同的字体、大小、颜色和样式会方便许多。 这个新功能可能要感谢 Pango,它现在支持一个称为 GMarkup 的小型标记语言。GMarkup 是一种类似于轻量级 XML 的语法,只要将标记嵌入您提供给各种 gtk_*() 函数的字符串,就可指定不同的文本样式。这里是一个示例: 清单 7. Pango 标记示例
#include <gtk/gtk.h>
int
main (int argc, char **argv)
{
GtkWidget *window;
GtkWidget *label;
gchar *markup_text;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (window), "destroy",
gtk_main_quit, NULL);
label = gtk_label_new ("A <span color=/"blue/">blue</span>
<big>and</big> <b>bold</b> label");
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
gtk_container_add (GTK_CONTAINER (window), label);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
| 并且要编译:
gcc `pkg-config --cflags --libs gtk+-2.0` -o label-markup label-markup.c
| 代码示例在运行时将类似于: Pango 标记 键盘导航 GTK+ 2 可以方便地创建仅使用键盘就可容易地访问的用户界面,这要归功于几个新的功能部件。首先, 在不同窗口构件之间切换焦点要比在 GTK+ 1 中更有可预知性。 只要使用 Tab 键和方向键,每件事都将按期望的那样工作。 其次,一个新的窗口构件 ― GtkDialog,能自动处理 Esc 键并关闭对话框。 第三,现在很容易创建键盘快捷键,也称为助记符。 要创建具有助记符的按钮,只要执行如下命令:
button = gtk_button_new_with_mnemonic ("_Quit");
| 然后就可以通过按 Alt+Q 来激活该按钮。前面有一个下划线的字符将被加上下划线,说明它代表一个键盘快捷键。 下面的示例演示了助记符在 notebook 页和按钮中的使用: GTK+ 2 助记符示例
#include <gtk/gtk.h>
int
main (int argc, char **argv)
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *label;
GtkWidget *page;
GtkWidget *notebook;
GtkWidget *button;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (window), "destroy",
gtk_main_quit, NULL);
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
/* Create our notebook and two pages, with mnemonics. */
notebook = gtk_notebook_new ();
gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
label = gtk_label_new_with_mnemonic ("Page _1");
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
gtk_label_new ("Page one"), label);
label = gtk_label_new_with_mnemonic ("Page _2");
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
gtk_label_new ("Page two"), label);
/* Create a button with a mnemonic as well. */
button = gtk_button_new_with_mnemonic ("_Quit");
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, TRUE, 0);
/* Make the quit button actually quit. */
g_signal_connect (button, "clicked", gtk_main_quit, NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
| 要编译:
gcc `pkg-config --cflags --libs gtk+-2.0` -o mnemonics mnemonics.c
| 请注意产生的图像中的助记符: GTK+ 助记符 GtkTreeView GtkTreeView 是替代 GtkCList 和 GtkCTree 的新的树和列表窗口构件。 以前,在数据和视图之间只有很少的逻辑分隔,并且很难编写定制单元绘制器。 使用 GtkTreeView,这些问题都得到了解决。作为一种附带的优点,GtkTreeView 有一个可编辑的文本单元,并且对一些吸引人的东西出现生动的扩展箭头。 运行中的 GtkTreeView GtkTextView 新的 GtkTextView 窗口构件在旧的 GtkText 窗口构件的基础上做了很大改进。它有很多出色的功能部件:
- 它支持混合字体、样式和文本颜色的使用,可以设置行距并且逐行进行调整。
- 因为所有文本都是用 UTF-8 表示的并且使用 Pango 显示,所以 GtkTextView 是完全国际化的。
- 长的行可以自动换行或按照字符换行(如果喜欢)。
- 可以嵌入图像,甚至是其它窗口构件。
- 因为 GtkTextView 使用“模型/视图/控制器”设计,所以它支持同一个文本缓冲区的多个视图。
这里是经过渲染后新的 GtkTextView 窗口构件的样子: 运行中的 GtkTextView 结束语 现在我们已经很好地讨论了 GTK+ 2 中可用的新功能,我们可以准备好开始研究 GNOME 2 平台的其他部分。 请阅读下一篇文章,届时我们将研究新的 Glib-2 对象系统。 到时再见! 参考资料
作者简介 Mikael Hallendal 是瑞典的 CodeFactory的 GNOME 开发人员,目前正从事 MrProject(一种 GNOME 项目管理应用程序)。另外,Mikael 正在为 GNOME 2.0 开发一种称为“Yelp”的帮助浏览器,并且还在维护 DevHelp(一种开发人员的文档浏览器)。 好象还不够,Mikael 还是 Gentoo Linux的“桌面小组负责人”(Desktop Team Leader)。 | Richard Hult 为 CodeFactory工作, 并且成为一名 GNOME 开发人员大约已有三年时间。在 CodeFactory 中,Richard 维护 MrProject(一种 GNOME 项目管理应用程序)。Richard 还是 Oregano(一种 GNOME 电路设计应用程序)的作者和维护者。 | |