Єдина Країна! Единая Страна!

GTK+ — 5. Діалоги

Квітень 2nd, 2009

У цій частині я коротко розповім про діалоги у GTK+. Діалог (dialog) — це незамінний елемент сучасних графічних користувацьких інтерфейсів. Діалоги використовуються для “спілкування” програми з користувачами. Наприклад, для отримання від користувача певних даних, зміни існуючих, тощо. Або ж про надання користувачу певної інформації від програми: інформаційні та повідомлення про помилки, тощо.

Інформаційні діалоги

Інформаційні діалоги використовуються для надання користувачам певної інформації. Вони містять, як текстову, так і графічну інформацію.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <gtk /gtk.h>
 
void show_info(GtkWidget *widget, gpointer window)
{
    GtkWidget *dialog;
 
    dialog = gtk_message_dialog_new(window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Download Completed", "title");
    gtk_window_set_title(GTK_WINDOW(dialog), "Information");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}
 
void show_error(GtkWidget *widget, gpointer window)
{
    GtkWidget *dialog;
 
    dialog = gtk_message_dialog_new(window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Error loading file");
    gtk_window_set_title(GTK_WINDOW(dialog), "Error");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}
 
void show_question(GtkWidget *widget, gpointer window)
{
    GtkWidget *dialog;
 
    dialog = gtk_message_dialog_new(window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "Are you sure to quit?");
    gtk_window_set_title(GTK_WINDOW(dialog), "Question");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}
 
void show_warning(GtkWidget *widget, gpointer window)
{
    GtkWidget *dialog;
 
    dialog = gtk_message_dialog_new(window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Unallowed operation");
    gtk_window_set_title(GTK_WINDOW(dialog), "Warning");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
}
 
int main( int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *table;
 
    GtkWidget *info;
    GtkWidget *warn;
    GtkWidget *que;
    GtkWidget *err;
 
    gtk_init(&argc, &argv);
 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 220, 150);
    gtk_window_set_title(GTK_WINDOW(window), "Message dialogs");
 
    table = gtk_table_new(2, 2, TRUE);
    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
    gtk_table_set_col_spacings(GTK_TABLE(table), 2);
 
    info = gtk_button_new_with_label("Info");
    warn = gtk_button_new_with_label("Warning");
    que = gtk_button_new_with_label("Question");
    err = gtk_button_new_with_label("Error");
 
    gtk_table_attach(GTK_TABLE(table), info, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 3, 3);
    gtk_table_attach(GTK_TABLE(table), warn, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 3, 3);
    gtk_table_attach(GTK_TABLE(table), que, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 3, 3);
    gtk_table_attach(GTK_TABLE(table), err, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 3, 3);
 
    gtk_container_add(GTK_CONTAINER(window), table);
    gtk_container_set_border_width(GTK_CONTAINER(window), 15);
 
    g_signal_connect(G_OBJECT(info), "clicked", G_CALLBACK(show_info), (gpointer) window);
    g_signal_connect(G_OBJECT(warn), "clicked", G_CALLBACK(show_warning), (gpointer) window);
    g_signal_connect(G_OBJECT(que), "clicked", G_CALLBACK(show_question), (gpointer) window);
    g_signal_connect(G_OBJECT(err), "clicked", G_CALLBACK(show_error), (gpointer) window);
    g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window));
 
    gtk_widget_show_all(window);
 
    gtk_main();
 
    return 0;
}
</gtk>

У цьому прикладі ми показуємо чотири інформаційних діалоги різних типів: Information, Warning, Question та Error.

1
2
3
4
5
6
GtkWidget *dialog;
dialog = gtk_message_dialog_new(window,
           GTK_DIALOG_DESTROY_WITH_PARENT,
           GTK_MESSAGE_QUESTION,
           GTK_BUTTONS_YES_NO,
           "Are you sure to quit?");

У функції the show_question(), ми відображаємо інформаційний діалог. Сам діалог створюється за допомогою функції gtk_message_dialog_new(). Параметри цієї функції вказують на те, який саме діалог ми бажаємо створити. Константа GTK_MESSAGE_QUESTION створює діалог типу Question (питання). GTK_BUTTONS_YES_NO створить діалог з двома кнопками — “Так” і “Ні”. Останнім параметром завжди є текст, який відображатиметься на діалозі.

1
2
3
gtk_window_set_title(GTK_WINDOW(dialog), "Warning");
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);

Тут ми задаємо заголовок для діалогу. І запускаємо його. Дестроїти діалог слід власноруч.


GtkAboutDialog

Діалог GtkAboutDialog відображає інформацію про програму. GtkAboutDialog може відображати логотип, назву програми, її версію, копірайт, майданчик тенет і ліцензію. А також перелік авторів, авторів документацію, перекладачів, і дизайнерів.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <gtk/gtk.h>
 
 
void show_about(GtkWidget *widget, gpointer data)
{
    GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file("battery.png", NULL);
 
    GtkWidget *dialog = gtk_about_dialog_new();
    gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dialog), "Battery");
    gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), "0.9");
    gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog),  "(c) Jan Bodnar");
    gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), "Battery is a simple tool for battery checking.");
    gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog), "http://www.batteryhq.net");
    gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), pixbuf);
    g_object_unref(pixbuf), pixbuf = NULL;
    gtk_dialog_run(GTK_DIALOG (dialog));
    gtk_widget_destroy(dialog);
}
 
int main( int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *about;
    GdkPixbuf *battery;
 
    gtk_init(&argc, &argv);
 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 220, 150);
    gtk_window_set_title(GTK_WINDOW(window), "Battery");
 
    gtk_container_set_border_width(GTK_CONTAINER(window), 15);
    gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
 
    battery = gtk_image_get_pixbuf(GTK_IMAGE(gtk_image_new_from_file("battery.png")));
 
    g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(show_about), (gpointer) window);
    g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window));
 
    gtk_widget_show_all(window);
 
    gtk_main();
 
    return 0;
}

Даний код створює діалог GtkAboutDialog. Для того, щоб відобразити діалог about, слід клацнути на вікні.

1
GtkWidget *dialog = gtk_about_dialog_new();

Створюємо GtkAboutDialog.

1
2
3
gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dialog), "Battery");
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), "0.9");
gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), "(c) Jan Bodnar");

Вищевказані функціх задають назву, версію та копірайт для відображення на діалозі.

1
2
3
4
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file("battery.png", NULL);
...
gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), pixbuf);
g_object_unref(pixbuf), pixbuf = NULL;

А цей код створює і відображає логотип.

dialog_about

GtkFontSelectionDialog

Усі вищеописані діалоги були такими, що виводили інформацію користувачеві. Є у GTK+ й такі діалоги, які просять користувача ввести певну інформацію, зчитують її, і передають програмі.

Гарним прикладом може слугувати GtkFontSelectionDialog, діалог для вибору шрифту. Як не дивно, за звичай, використовується у програмах, де необхідне форматування тексту.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <gtk/gtk.h>
 
 
void select_font(GtkWidget *widget, gpointer label)
{
    GtkResponseType result;
 
    GtkWidget *dialog = gtk_font_selection_dialog_new("Select Font");
    result = gtk_dialog_run(GTK_DIALOG(dialog));
 
    if (result == GTK_RESPONSE_OK || result == GTK_RESPONSE_APPLY) {
        PangoFontDescription *font_desc;
        gchar *fontname = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(dialog));
 
        font_desc = pango_font_description_from_string(fontname);
 
        gtk_widget_modify_font(GTK_WIDGET(label), font_desc);
 
        g_free(fontname);
    }
 
  gtk_widget_destroy(dialog);
}
 
int main( int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *label;
    GtkWidget *vbox;
 
    GtkWidget *toolbar;
    GtkToolItem *font;
 
    gtk_init(&argc, &argv);
 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 280, 200);
    gtk_window_set_title(GTK_WINDOW(window), "Font Selection Dialog");
 
    vbox = gtk_vbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER(window), vbox);
 
 
    toolbar = gtk_toolbar_new();
    gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
 
    gtk_container_set_border_width(GTK_CONTAINER(toolbar), 2);
 
    font = gtk_tool_button_new_from_stock(GTK_STOCK_SELECT_FONT);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), font, -1);
 
    gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 5);
 
    label = gtk_label_new("ZetCode");
    gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
    gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 5);
 
    g_signal_connect(G_OBJECT(font), "clicked", G_CALLBACK(select_font), label);
    g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
 
    gtk_widget_show_all(window);
 
    gtk_main();
 
    return 0;
}

Тут ми помістили у центр вікна текстову мітку. І відображаємо діалог вибору шрифту при натисненні на кнопку на панелі.

1
2
GtkWidget *dialog = gtk_font_selection_dialog_new("Select Font");
result = gtk_dialog_run(GTK_DIALOG(dialog));

Створюємо і показуємо GtkFontSelectionDialog.

1
2
3
4
5
6
7
8
9
10
if (result == GTK_RESPONSE_OK || result == GTK_RESPONSE_APPLY) {
    PangoFontDescription *font_desc;
    gchar *fontname = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(dialog));
 
    font_desc = pango_font_description_from_string(fontname);
 
    gtk_widget_modify_font(GTK_WIDGET(label), font_desc);
 
    g_free(fontname);
}

Якщо користувач натискає кнопку OK або APPLY, дані передаються нам. Ми отримуємо обраний користувачем шрифт. І змінюємо відповідним чином нашу текстову мітку.

dialog_fontselection

GtkColorSelectionDialog

GtkColorSelectionDialog слугує для вибору користувачем кольору.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <gtk/gtk.h>
 
 
void select_font(GtkWidget *widget, gpointer label)
{
    GtkResponseType result;
    GtkColorSelection *colorsel;
 
    GtkWidget *dialog = gtk_color_selection_dialog_new("Font Color");
    result = gtk_dialog_run(GTK_DIALOG(dialog));
 
    if (result == GTK_RESPONSE_OK) {
        GdkColor color;
 
        colorsel = GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(dialog)->colorsel);
        gtk_color_selection_get_current_color(colorsel, &color);
 
        gtk_widget_modify_fg(GTK_WIDGET(label), GTK_STATE_NORMAL, &color);
    }
 
    gtk_widget_destroy(dialog);
}
 
 
int main( int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *widget;
    GtkWidget *label;
    GtkWidget *vbox;
 
    GtkWidget *toolbar;
    GtkToolItem *font;
 
    gtk_init(&argc, &argv);
 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 280, 200);
    gtk_window_set_title(GTK_WINDOW(window), "Color Selection Dialog");
 
    vbox = gtk_vbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER(window), vbox);
 
 
    toolbar = gtk_toolbar_new();
    gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
 
    gtk_container_set_border_width(GTK_CONTAINER(toolbar), 2);
 
    font = gtk_tool_button_new_from_stock(GTK_STOCK_SELECT_COLOR);
    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), font, -1);
 
    gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 5);
 
    label = gtk_label_new("ZetCode");
    gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
    gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 5);
 
    g_signal_connect(G_OBJECT(font), "clicked", G_CALLBACK(select_font), label);
    g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
 
    gtk_widget_show_all(window);
 
    gtk_main();
 
    return 0;
}

Данй приклад мало чим відрізняється від попереднього. Цього разу ми змінуюємо колір нашої мітки.

1
2
GtkWidget *dialog = gtk_color_selection_dialog_new("Font Color");
result = gtk_dialog_run(GTK_DIALOG(dialog));

Створюємо GtkColorSelectionDialog.

1
2
3
4
5
6
7
8
9
if (result == GTK_RESPONSE_OK)
{
    GdkColor color;
 
    colorsel = GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(dialog)->colorsel);
    gtk_color_selection_get_current_color(colorsel, &color);
 
    gtk_widget_modify_fg(GTK_WIDGET(label), GTK_STATE_NORMAL, &color);
 }

Якщо користувач натиснув OK, ми отримуємо від діалогу обраний користуваче колір, і присвоюємо його мітці.

dialog_colorselection

Дана стаття є перекладом. Оригінал тут.

Коментарі

коментарі

Powered by Facebook Comments

Leave a Reply