65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Glade 和 GTK 设计基于对话框的应用程序

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.55/5 (4投票s)

2008年1月24日

CPOL

6分钟阅读

viewsIcon

47834

downloadIcon

261

使用 GTK 和 Glade 设计跨平台基于对话框的应用程序

引言

许多人希望构建可以重新编译以在 Windows、Linux 或 Mac 上运行的跨平台应用程序。GTK 是 Linux 世界中一个流行的图形库,许多开发人员使用 Glade UI 生成器来设计 GUI,它会生成 GTK 代码。

在本教程中,我们将使用适用于 Windows 的跨平台 GUI 生成器 Glade 来创建一个简单的基于对话框的应用程序。我(表示歉意地)借用了 Dr. Asad Altimeemy 在他的文章 A Beginner's Guide to Dialog Based Applications 中使用的对话框应用程序。要使用本指南,您必须先安装 GTK+/Win32 开发环境

创建新项目

启动 Glade。您应该会看到一个“项目”窗口、“属性”窗口和一个“工具箱”窗口。如果这些不可见,请在“项目”窗口的“视图”菜单中打开它们。

image001.png

通过单击“工具箱”窗口中的“窗口”控件(左上角)开始设计您的对话框。您应该会看到一个新窗口,如下图所示。

image002.png

转到“属性”窗口中的“控件”窗格。将“名称”字段的值更改为 NameList,将“标题”字段的值更改为 Name List。接下来,在“工具箱”窗口中选择“固定位置”图标(倒数第二行的最后一个控件),然后单击您的对话框窗口。

image003.png

通过按“项目”窗口中的“保存”按钮并输入您想使用的目录来保存您的项目。我使用C:\Glade\NameList

设计对话框

我们将设计一个使用下图所示对话框的应用程序。我们将使用“工具箱”窗口第三行中的标签、文本、组合框和文本视图控件来创建对话框。

image004.png

请按照以下分步说明来制作对话框

首先,添加标签。按“工具箱”窗口中的“标签”按钮。单击对话框以放置标签,然后用鼠标拖动以定位它。您可以用鼠标调整大小,但我发现更容易单击“属性”窗口中的“通用”窗格并在“宽度”字段中输入一个值。单击“属性”窗口中的“控件”窗格,然后在“标签”字段中输入标签文本。创建三个标签,名称分别为 TitleFirst NameLast Name

接下来,添加组合框。单击“工具箱”窗口中的组合框按钮,然后单击对话框以放置它。单击“属性”窗口中的“控件”窗格,将名称更改为 comboTitle,并在“项目”字段中输入 MrMrsMissMsDr,如下图所示。

image005.png

现在添加文本框。单击“工具箱”窗口中的文本框按钮,然后单击对话框以放置它。通过在“属性”窗口的“通用”窗格的“宽度”字段中输入 100 来调整长度。在“属性”窗口的“控件”窗格中更改“名称”字段。创建两个文本框,分别命名为 entryFirstNameentryLastName

添加按钮。使用“工具箱”窗口第四行中的“按钮”图标在对话框上放置两个按钮。更改“工具箱”窗口“控件”窗格上的名称。创建两个按钮,分别命名为 buttonAddButtonOK。单击对话框中的“添加”按钮,选择“属性”窗口中的“信号”窗格,然后单击“信号”字段中的“...”按钮。在“选择信号”窗口中选择“clicked”,然后按“确定”。处理函数 on_buttonAdd_clicked 应该会显示在“处理程序”字段中。按“添加”。对“确定”按钮重复此过程,为 clicked 事件添加处理程序 on_buttonOK_clicked

将您的对话框更改为不可调整大小的窗口。在“项目”窗口中单击“对话框”。单击“属性”窗口“控件”窗格中的“可调整大小”字段,并通过选中复选框和调整“通用”窗格中的“高度”和“宽度”值来调整大小。您现在应该有一个看起来像示例的对话框。请记住通过按“项目”窗口中的“保存”按钮来保存您的工作。

生成代码

转到“项目”窗口并单击“生成”以构建应用程序。浏览到项目目录下的 src 目录。您应该会看到以下文件:

image006.png

main.c – 主函数,它调用对话框的构造函数,然后运行事件处理循环。此文件仅生成一次,因此您可以在此处添加自己的初始化。如果您编辑对话框并重新生成代码,代码将不会更改。

interface.c – 通过调用一系列 GTK 函数来创建对话框的函数。您不应编辑此文件;每次更改对话框时都会重新生成它。

support.c – GTK 支持函数。此文件对于所有项目都相同,但不应更改。

callbacks.c – 用于填写每个事件操作的空函数。这是我们在此项目中唯一要更改的文件。

构建和运行

转到 msvc 子目录并单击 namelist.dsw 打开 Visual Studio。Glade 会生成 Visual Studio 6.0 项目文件;Visual Studio 会自动将其转换为较新版本。构建并运行代码。您应该会看到对话框,可以通过单击“x”图标关闭它。

添加事件处理程序

编写“确定”按钮处理程序,该处理程序会关闭对话框。打开 callback.c,转到空函数 on_buttonOK_clicked 并添加对函数 gtk_main_quit() 的调用。构建并运行,检查按下“确定”时对话框是否关闭。

void void on_buttonOK_clicked (GtkButton *button,
                               gpointer   user_data)
{
    gtk_main_quit();
}

接下来,我们添加“添加”按钮的处理程序代码。应用程序的逻辑是读取文本框和组合框中的文本,连接文本并将结果写入列表框。我们将分步将此逻辑添加到 on_bottonAdd_clicked 函数中。在使用每个控件之前,我们需要它们的指针。Glade 为每个控件分配一个与其名称相同的文本字符串。“lookup_widget”函数返回指向 GtkWidget 的指针,它是所有控件的基类。

    widgetFirstName = lookup_widget(GTK_WIDGET(button), "entryFirstName");
    widgetLastName = lookup_widget(GTK_WIDGET(button), "entryLastName");
    widgetTitle = lookup_widget(GTK_WIDGET(button), "comboTitle");
    widgetNameList = lookup_widget(GTK_WIDGET(button), "textviewNameList");

要设置列表框(Glade 将其称为视图框)中的制表符停止,我们需要构建一个制表符数组并将其分配给文本视图控件。我们还可以获取用于文本视图控件的文本缓冲区的指针,以便我们可以对其进行写入。

    ptaNameList = pango_tab_array_new_with_positions(2, TRUE, 
                                        PANGO_TAB_LEFT, 100, PANGO_TAB_LEFT, 200); 
    gtk_text_view_set_tabs(GTK_TEXT_VIEW(widgetNameList), ptaNameList);
    textNameList = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widgetNameList));

要读取控件中的文本,我们调用“get”函数。每个控件都有一个唯一的 get 函数。控件指针被转换为每个控件的控件指针。这些函数返回指向内部存储文本的指针;程序不需要分配空间。GTK 使用 UTF-8 可变长度 Unicode 格式的文本。ASCII 字符是 8 位,但外语字符可能高达 64 位。

    textFirstName = gtk_entry_get_text(GTK_ENTRY(widgetFirstName));
    textLastName = gtk_entry_get_text(GTK_ENTRY(widgetLastName));
    textTitle = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widgetTitle));

我们希望组合框和两个文本框中的文本显示在文本视图控件中。我们将文本插入到光标处的文本缓冲区中,文本缓冲区会在添加文本时自动移动。-1 参数要求函数自动计算字符串长度。

    gtk_text_buffer_insert_at_cursor(textNameList, textTitle, -1);
    gtk_text_buffer_insert_at_cursor(textNameList, "\t", -1); 
    gtk_text_buffer_insert_at_cursor(textNameList, textFirstName, -1); 
    gtk_text_buffer_insert_at_cursor(textNameList, "\t", -1); 
    gtk_text_buffer_insert_at_cursor(textNameList, textLastName, -1); 
    gtk_text_buffer_insert_at_cursor(textNameList, "\n", -1); 

既然我们已经转移了名字,我们就清除文本框中的文本并释放用于保存制表符位置的内存。

    gtk_entry_set_text(GTK_ENTRY(widgetFirstName),"");
    gtk_entry_set_text(GTK_ENTRY(widgetLastName),"");
    pango_tab_array_free(ptaNameList);

就是这样。这是完整的函数

void on_buttonAdd_clicked   (GtkButton       *button,
                             gpointer         user_data)
{
const gchar     *textFirstName;
const gchar     *textLastName;
const gchar     *textTitle;
GtkTextBuffer   *textNameList;
PangoTabArray   *ptaNameList;
GtkWidget       *widgetFirstName;
GtkWidget       *widgetLastName;
GtkWidget       *widgetTitle;
GtkWidget       *widgetNameList;

    widgetFirstName = lookup_widget(GTK_WIDGET(button), "entryFirstName");
    widgetLastName = lookup_widget(GTK_WIDGET(button), "entryLastName");
    widgetTitle = lookup_widget(GTK_WIDGET(button), "comboTitle");
    widgetNameList = lookup_widget(GTK_WIDGET(button), "textviewNameList");

    ptaNameList = pango_tab_array_new_with_positions(2, TRUE, 
                PANGO_TAB_LEFT, 100, PANGO_TAB_LEFT, 200); 
    gtk_text_view_set_tabs(GTK_TEXT_VIEW(widgetNameList), ptaNameList);
    textNameList = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widgetNameList));

    textFirstName = gtk_entry_get_text(GTK_ENTRY(widgetFirstName));
    textLastName = gtk_entry_get_text(GTK_ENTRY(widgetLastName));
    textTitle = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widgetTitle));

    gtk_text_buffer_insert_at_cursor(textNameList, textTitle, -1);
    gtk_text_buffer_insert_at_cursor(textNameList, "\t", -1); 
    gtk_text_buffer_insert_at_cursor(textNameList, textFirstName, -1); 
    gtk_text_buffer_insert_at_cursor(textNameList, "\t", -1); 
    gtk_text_buffer_insert_at_cursor(textNameList, textLastName, -1); 
    gtk_text_buffer_insert_at_cursor(textNameList, "\n", -1); 

    gtk_entry_set_text(GTK_ENTRY(widgetFirstName),"");
    gtk_entry_set_text(GTK_ENTRY(widgetFirstName),"");
    gtk_entry_set_text(GTK_ENTRY(widgetLastName),"");
    pango_tab_array_free(ptaNameList);
    gtk_entry_set_text(GTK_ENTRY(widgetLastName),"");
    pango_tab_array_free(ptaNameList);
}

结论

希望这能让您对 Glade/GTK 如何用于构建跨平台应用程序有所了解。示例中显示的 C 代码也可以在 Linux 机器上编译和运行,并具有 Linux GUI 样式。

历史

  • 2008 年 1 月 24 日 -- 发布原始版本
© . All rights reserved.