G0398 发表于 2014-11-22 12:44:52

C语言GUI程序设计-GTK图文系列-对话框

这一讲主要讲解GTK中的对话框部件,GtkDialog
GtkDialog提供一种弹出窗口与用户交互,就是所谓的对话框。GtkDialog是GTK中所有对话框的“基类”,我们常用的对话框有关于对话框和消息框。

例程截图:



#include <gtk/gtk.h>

void button_about_click(GtkButton *button,gpointer user_data)
{
    GtkWidget *about_dialog = gtk_about_dialog_new();
    const gchar *author[] = {"G0398",NULL};
    gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about_dialog),"dialog demo.exe");
    gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about_dialog),"v1.0");
    gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about_dialog),"2014 fishc inc.");
    gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about_dialog),"a simple program to display dialogs.");
    gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about_dialog),"no license");
    gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about_dialog),"http://bbs.fishc.com");
    gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about_dialog),&author);
    gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(about_dialog),"favicon.ico");
    gtk_dialog_run(GTK_DIALOG(about_dialog));
    gtk_widget_destroy(about_dialog);
}
void button_info_message_click(GtkButton *button,gpointer user_data)
{
    GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(user_data), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO,GTK_BUTTONS_OK,"information");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}
void button_warning_message_click(GtkButton *button,gpointer user_data)
{
    GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(user_data), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING,GTK_BUTTONS_OK,"warning");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}
void question_answer_callback(GtkDialog *dialog,gint response_id,gpointer user_data)
{
    if(response_id == GTK_RESPONSE_YES)
    {
      g_print("your anwser is yes!\n");
    }
    else if(response_id == GTK_RESPONSE_NO)
    {
      g_print("your anwser is no!\n");
    }
}
void button_question_message_click(GtkButton *button,gpointer user_data)
{
    gint response_id = 0;
    GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(user_data), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,GTK_BUTTONS_YES_NO,"are you sure?");
    g_signal_connect(GTK_WIDGET(dialog), "response", G_CALLBACK(question_answer_callback), NULL);
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}
void button_warning_error_click(GtkButton *button,gpointer user_data)
{
    GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(user_data), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,GTK_BUTTONS_OK,"something wrong!");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}
void button_login_dialog_click(GtkButton *button,gpointer user_data)
{
    GtkWidget *dialog;
    GtkLabel *label = GTK_LABEL(user_data);
    gint response_id = 0;
    GtkWidget *content_area,*fixed;
    GtkWidget *label_name,*entry_name,*label_pwd,*entry_pwd;

    dialog = gtk_dialog_new();
    content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
    fixed = gtk_fixed_new();
    gtk_widget_set_size_request(GTK_WIDGET(fixed),220,120);
    gtk_container_add(GTK_CONTAINER(content_area), fixed);
    label_name = gtk_label_new("name: ");
    label_pwd = gtk_label_new("password: ");
    gtk_fixed_put(GTK_FIXED(fixed), label_name, 5,20);
    gtk_fixed_put(GTK_FIXED(fixed), label_pwd, 5,50);
    entry_name = gtk_entry_new();
    entry_pwd = gtk_entry_new();
    gtk_entry_set_visibility(GTK_ENTRY(entry_pwd), FALSE);
    gtk_fixed_put(GTK_FIXED(fixed), entry_name, 85,20);
    gtk_fixed_put(GTK_FIXED(fixed), entry_pwd, 85,50);
    gtk_widget_show_all(fixed);
    gtk_dialog_add_button(GTK_DIALOG(dialog), "login", 0xa1);
    gtk_dialog_add_button(GTK_DIALOG(dialog), "cancel", 0xa2);
    response_id = gtk_dialog_run(GTK_DIALOG(dialog));
    if(response_id == 0xa1)
    {
      gtk_label_set_text(label, gtk_entry_get_text(GTK_ENTRY(entry_name)));
    }
    else if(response_id == 0xa2)
    {
      gtk_label_set_text(label, "user cancel");
    }

    gtk_widget_destroy(dialog);
}
int main(int argc,char *argv[])
{
    GtkWidget *window,*fixed;
    GtkWidget *button_about,*button_info_message,*button_warning_message,*button_question_message,*button_error_message;
    GtkWidget *button_dialog_for_user_login,*label_user_info;

    gtk_init(&argc,&argv);
    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),"hello fishc - GtkDialog");
    gtk_widget_set_size_request(GTK_WIDGET(window),300,200);

    fixed = gtk_fixed_new();
    gtk_container_add(GTK_CONTAINER(window), fixed);

    button_about = gtk_button_new_with_label("about this program");
    g_signal_connect(GTK_WIDGET(button_about), "clicked", G_CALLBACK(button_about_click), NULL);
    gtk_fixed_put(GTK_FIXED(fixed), button_about, 5,5);

    button_info_message = gtk_button_new_with_label("info message");
    g_signal_connect(GTK_WIDGET(button_info_message), "clicked", G_CALLBACK(button_info_message_click), window);
    gtk_fixed_put(GTK_FIXED(fixed), button_info_message, 5,45);

    button_warning_message = gtk_button_new_with_label("warning message");
    g_signal_connect(GTK_WIDGET(button_warning_message), "clicked", G_CALLBACK(button_warning_message_click), window);
    gtk_fixed_put(GTK_FIXED(fixed), button_warning_message, 125,45);

    button_question_message = gtk_button_new_with_label("question message");
    g_signal_connect(GTK_WIDGET(button_question_message), "clicked", G_CALLBACK(button_question_message_click), window);
    gtk_fixed_put(GTK_FIXED(fixed), button_question_message, 5,85);

    button_error_message = gtk_button_new_with_label("error message");
    g_signal_connect(GTK_WIDGET(button_error_message), "clicked", G_CALLBACK(button_warning_error_click), window);
    gtk_fixed_put(GTK_FIXED(fixed), button_error_message, 145,85);

    label_user_info = gtk_label_new("user info ");
    gtk_fixed_put(GTK_FIXED(fixed), label_user_info, 5,165);

    button_dialog_for_user_login = gtk_button_new_with_label("a dialog for user login");
    g_signal_connect(GTK_WIDGET(button_dialog_for_user_login), "clicked", G_CALLBACK(button_login_dialog_click), label_user_info);
    gtk_fixed_put(GTK_FIXED(fixed), button_dialog_for_user_login, 5,125);

    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

先看下关于对话框,关于对话框一般在软件的菜单栏Help->About里出现,显示了这个软件的名称,版本号,描述,作者,授权等信息。




GtkAboutDialog
GtkAboutDialog提供了一种简便的方式来设置关于对话框,我们不用考虑对话框中子部件的布局,以及对话框的大小,只要设置一些需要显示的属性就可以了。
gtk_about_dialog_new()
这个函数用来创建一个关于对话框,无参数。
然后通过以系列的set函数设置对话框中要显示的属性。
gtk_about_dialg_set_xxxxxxxx就是我们要设置的属性名称,比如这里要设置软件的版本号,就使用这个函数:
gtk_about_dialog_set_version这个函数有两个参数,第一个为GtkAboutDialog,第二个为要设置的版本号值。

一个个设置完后,调用对话框的显示函数来显示对话框。
gtk_dialog_run这个函数用来显示对话框,第一个参数为要显示的对话框。
显示完成后通过
gtk_widget_destroy
函数销毁对话框资源。

GtkMessageDialog
GtkMessageDialog是GTK中的消息框,和win32下的MessageBox api作用是一样的。



消息框的类型有信息框,警告框,错误提示框和提供选择的问题框。

gtk_message_dialog_new用来创建一个消息框,这个函数有5个必选参数和1个可选参数。

第一个参数为承载这个消息框的父窗体,
第二个参数为对话框的标志位,用来设置对话框为模态对话框,
第三个参数为对话框的类型,如信息框,警告框,等。这是一个枚举类型,定义为:
typedef enum {
GTK_MESSAGE_INFO,
GTK_MESSAGE_WARNING,
GTK_MESSAGE_QUESTION,
GTK_MESSAGE_ERROR,
GTK_MESSAGE_OTHER
} GtkMessageType;第四个参数为按钮类型,用来指示对话框中显示的按钮,也是一个枚举类型,定义为:
typedef enum {
GTK_BUTTONS_NONE,
GTK_BUTTONS_OK,
GTK_BUTTONS_CLOSE,
GTK_BUTTONS_CANCEL,
GTK_BUTTONS_YES_NO,
GTK_BUTTONS_OK_CANCEL
} GtkButtonsType;第五个参数为一个格式化字符串,和printf函数的第一个参数一样的,用来格式化字符串。
最后一个可选参数是为了给格式化字符串提供参数值。

我们可以注册GtkDialog的 response 信号来获取对话框的反馈信息(还有其它的方式),比如要获取


的用户选择,可以注册回调函数来获取response_id,通过判断response_id 来获取用户选择。
response id 取值为一个整形,其预定义取值为枚举类型,定义为:
typedef enum {
GTK_RESPONSE_NONE         = -1,
GTK_RESPONSE_REJECT       = -2,
GTK_RESPONSE_ACCEPT       = -3,
GTK_RESPONSE_DELETE_EVENT = -4,
GTK_RESPONSE_OK         = -5,
GTK_RESPONSE_CANCEL       = -6,
GTK_RESPONSE_CLOSE      = -7,
GTK_RESPONSE_YES          = -8,
GTK_RESPONSE_NO         = -9,
GTK_RESPONSE_APPLY      = -10,
GTK_RESPONSE_HELP         = -11
} GtkResponseType;
GtkDialog
下面来看看GtkDialog,它为我们提供了一种显示对话框的方式,将要显示的内容添加到其内部,调用run函数就可以显示出来了,例如这个登录框:



先新建一个GtkDialog,然后获取其内容区域,把要显示的东西添加到其内容区域即可。
gtk_dialog_get_content_area这个函数用来获取对话框的内容区域,返回值为内容区域的指针。
使用函数
gtk_dialog_add_button为对话框添加按钮,可以设置按钮的response_id,为自定义的id。
例程中添加了两个按钮,一个login一个cancel,其响应id分别为0xa1,0xa2。
设置完成后,调用
gtk_dialog_run函数即可显示自定义的对话框,其实这个函数有个返回值就是response_id,可以直接用它的返回值来判断用户选择状态,不用注册 response 信号的回调那种方式了。

好了,对话框就说这么多,下一讲来说GTK中的树状部件和列表部件。

页: [1]
查看完整版本: C语言GUI程序设计-GTK图文系列-对话框