鱼C论坛

 找回密码
 立即注册
查看: 2189|回复: 0

[技术交流] C语言GUI程序设计-GTK图文系列-对话框

[复制链接]
发表于 2014-11-22 12:44:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

例程截图:
gtk_dialog_demo.png

#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里出现,显示了这个软件的名称,版本号,描述,作者,授权等信息。

gtk_about_dialog.png


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

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

GtkMessageDialog
GtkMessageDialog是GTK中的消息框,和win32下的MessageBox api作用是一样的。
gtk_info_dialog.png gtk_warning_dialog.png gtk_error_dialog.png gtk_question_dialog.png


消息框的类型有信息框,警告框,错误提示框和提供选择的问题框。
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函数就可以显示出来了,例如这个登录框:
gtk_dialog_userlogin.png


先新建一个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中的树状部件和列表部件。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-18 09:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表