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

Archive for the 'GTK+' Category

GTK+ — 8. GtkImage та GtkIconView

Вівторок, Серпень 11th, 2009

У цій частині трішки попрацюємо з графікою, а точніше, з кількома досить простими, але часто використовуваними віджетами для роботи з нею: GtkImage та GtkIconView.

GtkImage

GtkImage — досить простий віджет для відображення растрових зображень.

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
#include <gtk /gtk.h>
 
 
int main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *image;
 
    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), 230, 150);
    gtk_window_set_title(GTK_WINDOW(window), "Red Rock");
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
 
    gtk_container_set_border_width(GTK_CONTAINER(window), 2);
 
    image = gtk_image_new_from_file("redrock.png");
    gtk_container_add(GTK_CONTAINER(window), image);
 
    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>

У вищенаведеному прикладі ми завантажуємо, і відображаємо світлину замку.

Встановлюємо 2-піксельну рамку навколо зображення:

1
gtk_container_set_border_width(GTK_CONTAINER(window), 2);

Завантажуємо зображення з файлу і додаємо його до контейнеру:

1
2
image = gtk_image_new_from_file("redrock.png");
gtk_container_add(GTK_CONTAINER(window), image);

gtkimage

Read the rest of this entry »

GTK+ — 7. Прапорці та комбіновані списки

Середа, Квітень 22nd, 2009

Продовжуємо огляд віджетів основних елементів графічного користувацького інтерфейсу. Цього разу про кнопки-прапорці та комбіновані списки.

GtkCheckButton

GtkCheckButton — віджет, який має два стани: увімкнено і вимкнено. Стан “увімкнено” візуально відтворюється, як встановлений прапорець.

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
#include <gtk /gtk.h>
 
 
void toggle_title(GtkWidget *widget, gpointer window)
{
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
        gtk_window_set_title(window, "GtkCheckButton");
    } else {
        gtk_window_set_title(window, "");
    }
}
 
int main(int argc, char** argv)
{
    GtkWidget *window;
    GtkWidget *frame;
    GtkWidget *check;
 
    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), 230, 150);
    gtk_window_set_title(GTK_WINDOW(window), "GtkCheckButton");
 
 
    frame = gtk_fixed_new();
    gtk_container_add(GTK_CONTAINER(window), frame);
 
    check = gtk_check_button_new_with_label("Show title");
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
    GTK_WIDGET_UNSET_FLAGS(check, GTK_CAN_FOCUS);
    gtk_fixed_put(GTK_FIXED(frame), check, 50, 50);
 
    g_signal_connect_swapped(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    g_signal_connect(check, "clicked", G_CALLBACK(toggle_title), (gpointer) window);
 
    gtk_widget_show_all(window);
 
    gtk_main();
 
    return 0;
}
</gtk>

У нашому вищенаведеному прикладі ми створили просту кнопку-прапорець, заголовок до якої буде відображатись, або ж буде відсутнім, залежно від того, буде встановлено прапорець, чи ні.

Створюємо віджет GtkCheckButton, зі станок за замовчуванням “прапорець поставлено”:

1
2
check = gtk_check_button_new_with_label("Show title");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);

Тут ми прибираємо з нашої кнопки-прапорця фокус:

1
GTK_WIDGET_UNSET_FLAGS(check, GTK_CAN_FOCUS);

А цей код змінюєватиме заголовок кнопки в залежності від стану папорця:

1
2
3
4
5
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
    gtk_window_set_title(window, "GtkCheckButton");
} else {
    gtk_window_set_title(window, "");
}

gtkcheckbutton

Read the rest of this entry »

GTK+ — 6. Кнопки і текстові мітки

Понеділок, Квітень 13th, 2009

З цієї частини почнемо розглядати найпопулярніші графічні віджети, які надає GTK+. Першими будуть, як і слід, стандартні елементи графічного інтерфейсу, а саме: кнопки і текстові мітки.

GtkButton

Ось приклад простого вікна з кнопкою, при натисканні на яку викликається внутрішня функція gtk_main_quit(), котра завершує роботу програми:

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
#include <gtk /gtk.h>
 
 
int main(int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *fixed;
    GtkWidget *button;
 
    gtk_init(&argc, &argv);
 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "GtkButton");
    gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
 
    fixed = gtk_fixed_new();
    gtk_container_add(GTK_CONTAINER(window), fixed);
 
    button = gtk_button_new_with_label("Quit");
 
    gtk_fixed_put(GTK_FIXED(fixed), button, 50, 50);
    gtk_widget_set_size_request(button, 80, 35);
 
    g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_main_quit), G_OBJECT(window));
    g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
 
    gtk_widget_show_all(window);
 
    gtk_main();
 
    return 0;
}
</gtk>

Тут ми створюємо кнопку з міткою “Quit” (вийти):

1
button = gtk_button_new_with_label("Quit");

А тут прив’язуємо сигнал “clicked” кнопки до функції gtk_main_quit():

1
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtk_main_quit), G_OBJECT(window));

gtkbutton

Read the rest of this entry »

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);

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


Read the rest of this entry »

GTK+ — 4. Події та сигнали

Середа, Березень 25th, 2009

У цій частині я розповім про систему подій (events) та сигналів у бібліотеці GTK+. Власне, бібліотека GTK+ є “event driven system”, тобто, такою, що цілком побудована на основі системи подій та сигналів на них. Адже усі графічні додатки є “event driven”, тобто такими, мета яких реагувати на певні дії користувача (події), надсилати своєму коду сигнали, і обробляти їх.

Усе починається з того, що програма запускає головний цикл, який неперервно перевіряє наявність нових подій. Якщо ніяких подій не відбувається, програма тихенько собі спить, і нічогісінько не робить. У GTK+ повідомленнями про події є повідомлення від сервера X. Коли віджет генерує якусь подію, програма може на неї відреагувати. Програміст GTK+ може з’єднувати специфічні колбеки (callback) та сигнали. Сам callback є нічим іншим, як вказівником на звичайнісіньку функцію, яка реагуватиме на сигнал. Наприклад, маємо віджет “кнопка”, подію “натискання на кнопку”, і колбек (функцію), яка викликається при обробці події (натискання на кнопку).

У версії 2.0 сигнальну систему було перенесена з GTK до GLib, ось чому функції і типи, що описуються в цьому розділі мають префікс “g_” а не “gtk_”. Ми не будемо заглиблюватись в деталі, що до додаткових можливостей, які дає сигнальна система GLib 2.0 порівняно з сигнальною системою GTK 1.2.

Read the rest of this entry »