本人声明
1.本栏仅为归档自己看到的优秀文章;
2.文章版权归原作者所有;
3.因为个人水平有限,翻译难免有错误,请多多包涵。
原文地址
https://www.codeguru.com/cpp/cpp/creating-a-cc-gui-with-gtk.html
文章正文
基于GTK+创建一个GUI程序
作者: Manoj Debnath 发表于:2017.04.21
支持GUI开发是许多语言的核心功能之一。 C/C++标准语言并没有提供这种附属的库,就像我们使用的字符串库,IO库等等。这个缺点为开发人员提供了选择空间,开发者可以从众多能用语C/C++的GPU开发包中挑选合适的库。GTK+就是其中之一。它代表GIMP(GNU Image Manipulation Program)工具包,可用于编程现代GUI界面。
概述
GTK+的优势在于它的稳定和成熟,它的起源可以追溯到X Windows时代,同时它构建了当今Linux系统的核心GUI功能。 GTK完全用C语言编写,我们在Linux中常用的GTK+软件也是用C编写的。桌面管理器(如GENOME和XFCE)也是用GTK构建的。 GTK支持多种编程语言绑定,具体如下所示:
GTK与Python的绑定,叫做PyGTK
GTK与Java的绑定, 它与gtkmm非常相似
GTK与C++的绑定, 它是GTK+的官方C++绑定
GTK与Perl的绑定
GTK 与PHP的绑定
GTK 与C#的绑定,通过mono项目
GTK+应用程序不仅局限于Linux平台运行;它也可以移植到非UNIX / Linux平台上。
入门
在这里,我们将坚持使用GTK+的基本形式,它是Linux平台上的C的化身。GTK+下载的官方网站是https://www.gtk.org。该站点包含API文档,教程和其他常与GTK一起搭配使用的Gnome库。事实上,GTK就是建立在库之上的,例如:
Glib:它是一个通用实用程序库,支持线程、动态加载、事件循环、基本数据结构等功能。
GObject:这个库在不使用C++的情况下,在C语言中提供全功能的面向对象支持。该库有助于其他语言创建的语言绑定,使您可以轻松调用C接口。
Pango:这个库支持文本和布局渲染。
ATK:该库提供了对创建辅助工具(如粘滞键,屏幕阅读器等)的支持。
GDK(GIMP Drawing Toolkit):这是在Xlib之上提供底层绘图功能的图形库。
GdkPixBuf:该库提供图像处理功能。
Xlib:该库为Linux系统提供底层图形支持。
使用GTK编写代码时,我们经常发现许多基本数据类型都以’g’为前缀,如gint,gchar,gshort,gpointer等。这些数据类型确保可以在任何平台上,只需要重新编译代码而无需进行任何更改。这些数据类型在这些库中定义,有助于跨平台开发。
GUI编程的主要问题在于它本质上是面向对象的。因此,面向过程范式并不完全适合该方案。正是这个原因,尽管GTK是用C语言编写的,但它通过GObject库提供了对面向对象的支持。请注意,这种面向对象的支持与C ++无关。 C++有自己的GTK库,叫做gtkmm。 GObject在宏的帮助下,实现了一些面向对象的原则(比如多态和继承)。以下继承关系图将进一步阐明该观点。
图1: GObject继承关系结构图
GtkWindow是GtkBin的子类,或者说继承于GtkBin类,GtkBin本身又是GtkContainer的子类;因此,一个GtkWindow的对象可以调用GtkBin或GtkContainer中定义的函数。这是GTK中一个利用C语言强制执行面向对象行为的示例。
利用GTK编写GUI程序
让我们从用C语言编写的第一个GTK程序中了解一些内容。首先,我们需要包含头文件
#include <gtk/gtk.h>
现在,我们声明一个指向GtkWidget的指针,它只是我们示例程序中的一个窗口。而且,另一个GtkWidget指针将会是一个按钮。让我们回想一下,GtkWidget是继承结构控件的顶层存储类型。
GtkWidget *window;
GtkWidget *button;
接下来,我们利用main函数的命令行参数,调用gtk_init函数进行GTK+库的初始化工作。
gtk_init(&argc, &argv);
所有GTK+应用程序都要以这种方式来初始化;这是一句“必不可少”的代码。它解析命令行参数并返回到应用程序。因此,这些参数可用于改变应用程序的运行时行为。
现在,我们来创建窗体和按钮。
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
button = gtk_button_new_with_label
("Click Me!");
窗口的类型值GTK_WINDOW_TOPLEVEL表示创建的窗口将是有边框的顶层窗口。其他类型值可以是GTK_WINDOW_POPUP,这意味着将创建无边框对话窗口。
一旦我们创建了一个窗口,它就必须是可关闭的,这样就在可以在响应用户点击右上方的关闭按钮时,来进行应用程序的关闭操作。这意味着窗口必须能够响应事件(关闭事件)。与所有窗口系统一样,GTK+也实现了事件和事件处理程序。因为发出信号的代码是特定对象的内部代码,所以我们需要编写一个连接回调函数。典型回调函数的格式为:
void my_callback_function(GtkWidget *widget,
gpointer data);
第一个参数表示发出信号的控件,第二个参数是可用于任何目的的void指针。因此,处理窗口关闭事件的回调函数如下:
void destroy( GtkWidget *widget, gpointer data )
{
gtk_main_quit ();
}
函数gtk_main_quit()用来关闭应用程序。现在,我们必须将window对象与回调函数连接起来。
g_signal_connect (window, "destroy",
G_CALLBACK (destroy), NULL);
采用类似的方法,我们创建回调函数来处理按钮事件并将其与按钮控件连接起来。
void greet( GtkWidget *widget, gpointer data )
{
g_print ("Hi there! Welcome to GTK\n");
g_print ("%s clicked %d times\n",
(char*)data, ++counter);
}
g_signal_connect (GTK_OBJECT(button), "clicked",
G_CALLBACK (greet), "button");
由于按钮控件包含在窗口中,因此我们必须将其添加到容器中。
gtk_container_add (GTK_CONTAINER (window), button);
最后,我们使用gtk_widget_show_all()函数来显示内存中创建的控件,该函数引用我们创建的窗口。最后,通过调用gtk_main()函数来启动交互式进程。
gtk_widget_show_all(window);
gtk_main();
这是一个关键功能,因为通常C程序在执行最后一个语句后终止。在这里,它将程序的控制权传递给GTK +,并且在用户单击我们的示例中的关闭按钮触发gtk_main_quit事件之前,程序永远不会返回。
现在,让我们把代码整合在一起。
#include <gtk/gtk.h>
static int counter = 0;
void greet( GtkWidget *widget, gpointer data )
{
// printf equivalent in GTK+
g_print ("Hi there! Welcome to GTK\n");
g_print ("%s clicked %d times\n",
(char*)data, ++counter);
}
void destroy( GtkWidget *widget,gpointer data )
{
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 (window, "destroy",
G_CALLBACK (destroy), NULL);
/* Let's set the border width of the window to 20.
* You may play with the value and see the
* difference. */
gtk_container_set_border_width
(GTK_CONTAINER (window), 20);
button = gtk_button_new_with_label ("Click Me!");
g_signal_connect (GTK_OBJECT(button),
"clicked",G_CALLBACK (greet),
"button");
gtk_container_add (GTK_CONTAINER (window), button);
gtk_widget_show_all(window);
gtk_main ();
return 0;
}
利用Linux系统中的GCC来编译程序。
gcc main.c -o p1
`pkg-config --cflags --libs gtk+-2.0`
运行程序:
./p1
图2:程序运行截图
结论
GTK+拥有创建专业界面所需的所有GUI组件。使用GTK+进行GUI事件驱动程序设计的基本思想,与示例中显示的并没有太大区别。添加一些组件,使用不同类型的容器,调整布局,当然永远不要忘记查阅GTK+文档。专业程序员常用RAD工具(例如Glade之类的)来快速设计GUI界面。但是,首先尝试从头开始编写代码,能够了解程序执行的内容和执行方式。这对您以后的工作有很大的好处。
关于作者
Manoj Debnath
manosolireap@outlook.com
相关文章
Last.fm Open Sources C++ Moost Library Now Available
CppDepend Pro License for C\C++ open source project contributors
栏目导航
上一篇:技术文章翻译(五) – 利用.NET显示当前屏幕内容
下一篇:技术文章翻译(七) – 深入研究C++字符串流处理过程