代码改变世界

用GTK编写GUI程序

2011-06-15 20:17  htc开发  阅读(450)  评论(0编辑  收藏  举报

目录:

 

什么是GTK?

GTK(GIMP Toolkit,GIMP工具包)是用作图形用户界面开发的图形库.它遵守GPL(GNU公共许可协议)。你可以使用GTK创建开源的,免费的,或者是商业的程序.

之所以称它为GIMP工具包(GTK),是因为GTK创建时的最初目的是为了开发GIMP程序(通用图像处理程序).GTK的作者是:

GTK是面向对象(object-oriented)的程序用户接口.虽然是用C语言写成的,但是它使用了类(classes)和回调函数(callback function)的思想.

 

编译

编译GTK程序的时候,你需要告诉gcc你使用什么样的GTK库和它的具体位置,而gtk-config 命令"知道"这些情况

# gtk-config --cflags --libs

这个命令的输出看起来大概是下面的样子(依赖于你的系统) :

-I/opt/gnome/include/gtk-1.2 -I/opt/gnome/include/glib-1.2 -I/opt/gnome/lib/glib /include -I/usr/X11R6/include -L/opt/gnome/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -l Xext -lX11 -lm

参数解释:

-l library: 在预定的路径查找库名为liblibrary.a的库. 
-L path: 添加路径到库查找路径中. 
-I path: 添加路径到头文件的查找路径中 

要编译一个名为hello.c的程序,可以使用如下的命令:

gcc -o hello hello.c `gtk-config --cflags --libs`

参数-o后面输入的是编译的结果文件的名称.

 

第一个程序

我们假设你已经在你的系统里安装了GTK.可以从ftp.gtk.org的到GTK的最新版本.

让我们写下第一个程序,这个程序创建一个200x200象素大的空窗口.

#include <gtk/gtk.h>

int main( int   argc,
          char *argv[] )
{
    GtkWidget *window;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_widget_show  (window);

    gtk_main ();

    return(0);
}

GtkWidget是用来定义像窗口(window),按钮(button),标签(label)等等组件的一个变量类型, 在这个例子里,我们像这样定义一个窗口.:

GtkWidget *window;

void gtk_init(int *argc,char ***argv) 初始化工具包并且获取命令行参数.这个函数必须在组件定义之后使用

GtkWidget *gtk_window_new(GtkWindowType windowtype) 创建一个新的窗口,窗口类型(windowtype)可以是:

  • GTK_WINDOW_TOPLEVEL
  • GTK_WINDOW_DIALOG
  • GTK_WINDOW_POPUP

void gtk_widget_show(GtkWidget *widget) 函数显示窗口中的组件.在创建了一个组件或改变了组件属性的情况下,则这个函数就必须要用到.

void gtk_main(void) 准备将窗口和所有的组件显示在屏幕上,这个函数必须在GTK程序的最后调用.

让我们来使用一些窗口的属性,比如标题(titles),尺寸(size),位置(position)...

void gtk_window_set_title(GtkWindow *window,const gchar *title) 用来设定或更改窗口window的标题. 这个函数的第一个参数要求是GTKWindow类型的,而变量 window 是 GtkWidget 类型,所以在编译时,我们会因此得到一个警告.虽然最后的结果文件仍然是可以运行的,但最好还是自己来更正它.因此要使用GTK_WINDOW(GtkWidget *widget)作第一个参数. 第二个参数 title是gchar型.gchar在glib库中定义,它和char是一样的.

void gtk_window_set_default_size(GtkWindow *window, gint width, gint height) 设定window的尺寸.和gchar一样,gint是在glib库中定义的和int一样的类型 .

函数

void gtk_window_set_position(GtkWindow *window, GtkWindowPosition position)

设定window的位置.position 可以是:

  • GTK_WIN_POS_NONE
  • GTK_WIN_POS_CENTER
  • GTK_WIN_POS_MOUSE
  • GTK_WIN_POS_CENTER_ALWAYS

下面是个例子:

#include <gtk/gtk.h>

int main( int   argc,
          char *argv[] )
{
    GtkWidget *window;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),"Ýlk Program");
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window),300,300);
    gtk_widget_show  (window);

    gtk_main ();

    return(0);
}
 

信号和事件(Signals and Events)

在图形用户界面中,你需要用到鼠标和键盘。比如说,你可以按下一个按钮。为此,GTK提供了如下的函数:

guint gtk_signal_connect_object(GtkObject *object,const gchar *name,GtkSignalFu nc func,GtkObject *slot_object);

object 是发出信号的组件。比如说如果你想知道一个按钮是否已被按下,那么 object即为那个按钮,而name 是事件的名称,它可以是:

  • event
  • button_press_event
  • button_release_event
  • motion_notify_event
  • delete_event
  • destroy_event
  • expose_event
  • key_press_event
  • key_release_event
  • enter_notify_event
  • leave_notify_event
  • configure_event
  • focus_in_event
  • focus_out_event
  • map_event
  • unmap_event
  • property_notify_event
  • selection_clear_event
  • selection_request_event
  • selection_notify_event
  • proximity_in_event
  • proximity_out_event
  • drag_begin_event
  • drag_request_event
  • drag_end_event
  • drop_enter_event
  • drop_leave_event
  • drop_data_available_event
  • other_event

func 是事件发生时将要被调用的函数:下面是一个例子:

#include <gtk/gtk.h>

void close( GtkWidget *widget,gpointer *data)
{
    gtk_main_quit();
}

int main( int   argc,char *argv[] )
{
    GtkWidget *window;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_signal_connect (GTK_OBJECT (window), "destroy",
                        GTK_SIGNAL_FUNC (close), NULL);
    gtk_widget_show  (window);

    gtk_main ();

    return(0);
}

函数

gtk_signal_connect (GTK_OBJECT (window), "destroy",GTK_SIGNAL_FUNC (close), NULL)

监听窗口window的destroy事件.当窗口关闭时, close 就会被调用.而 close 函数又调用 gtk_main_quit() 结束程序运行.

关于事件和信号的细节将在以后介绍...

 

普通按钮(A ordinary button)

普通按钮一般用作在将它按下时让程序做特定的事情.在GTK库中,可以用两种方式创建一个按钮:

  1. GtkWidget* gtk_button_new (void);
  2. GtkWidget* gtk_button_new_with_label (const gchar *label);

第一个函数创建一个没有标签的按钮(上面不显示任何东西).第二个函数创建一个带标签的函数 (字符串label将显示在上面).

在这儿,我们将使用一个新的函数:

void gtk_container_add(GtkContainer *container,GtkWidget *widget)

使用这个函数可以创建在窗口(一般的,可以是任何容器)中显示的按钮(也可以是任何其它的组件).在接下来的例子中,容器是一个窗口,而添加到容器中的组件是按钮。我们将在以后学习其它的一些容器。

关于普通按钮最重要的事无外乎就是要知道它是否已经被按下.而可以再一次使用gtk_signal_connect 函数来实现这个目的.使用gtk_signal_connect,可以调用另一个函数来执行“隐藏“在按钮后的功能。 下面是一个简单的例子:

#include <gtk/gtk.h>

void close( GtkWidget *widget,gpointer *data)
{
    gtk_main_quit();
}

void clicked(GtkWidget *widget,gpointer *data)
{
        g_print("Button Clicked/n");
}
int main( int   argc,char *argv[] )
{
    GtkWidget *window,*button;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_signal_connect (GTK_OBJECT (window), "destroy",
                        GTK_SIGNAL_FUNC (close), NULL);

    button=gtk_button_new_with_label("Button");
    gtk_container_add(GTK_CONTAINER(window),button);
    gtk_signal_connect(GTK_OBJECT(button),"clicked",
                       GTK_SIGNAL_FUNC(clicked),NULL);
    gtk_widget_show(button);

    gtk_widget_show(window);

    gtk_main ();

    return(0);
}