Продолжаем
разбираться в Gtk+. Возьмем за основу
наш
проект, в котором мы создали главное
окно и добавили элементы управления.
Имя нового проекта будет Gtk_p4. Таким
же образом, как было в предыдущих постах,
создадим файл main.c.
Напишем в файле
main.c главную функцию программы,
создадим главное окно, добавим элементы
управления (поле редактирование, кнопку,
метку текста), разместим все эти виджеты
в контейнере сетке. Ну вот, подошли к
самому интересному.
Следующей
задачей, поставим для себя, реализовать
возможность присваивать метке текст,
введенный в поле редактирование, по
нажатию на кнопку.
1) Если вводимый
текст пустая строка, по нажатию на кнопку
покажем сообщение, что строка пуста.
2) Если длинна
строки текста превышает 10-ти символом,
по нажатию на кнопку покажем сообщение,
что строка не должна превышать 10-ти
символов.
Ну вот, пробуем
написать код. Так как мы будем показывать
сообщение, то в нашем проекте нам
понадобится функция создания модального
диалога. Данную функцию мы позаимствуем
из проекта,
где мы показывали сообщение по нажатию
на кнопку мыши. Ниже показан код функции:
void
my_modal_dialog(GtkWindow* parent, gchar* str)
{
GtkWidget*
modal_dialog = gtk_message_dialog_new(parent,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
str);
gtk_dialog_run(GTK_DIALOG(modal_dialog));
gtk_widget_destroy(modal_dialog);
}
Так как мы должны
при каждом нажатие на кнопку определять
длину текста введенного в поле
редактирования, то напишем для этого
специальную функцию:
gint
get_string_length(const gchar *str) {
return strlen(str);
}
В самом начале
кода проекта после строчки
#include <gtk/gtk.h>
подключите
заголовочный файл с функциями для работы
со строками
#include <string.h>
Перед тем как
мы рассмотрим функцию, которая вызывается
при нажатие на кнопку, мы должны в самом
начале главной функции программы, где
мы определили указатели на наши объекты
(главного окна, сетки, поля редактирования,
кнопки, метки текста), определить массив
из трех указателей:
gpointer data[3];
Данный массив
мы передадим функции, которая вызывается
по нажатию на кнопку. Массив будет
содержать три указателя, указатель на
главное окно, указатель на метку текста
и указатель на поле редактирования.
После строчки кода, где мы добавляем
кнопку в контейнер — сетку:
gtk_grid_attach(GTK_GRID(grid),
button, 1, 0, 1, 1);
разместите код
добавления указателей в массив:
data[0] =
(gpointer)label;
data[1] =
(gpointer)entry;
data[2] =
(gpointer)window;
Дальше разместим
функцию, которая соединит кнопку с
именем button и функцию с именем
button_clicked, в которую мы и предадим
массив указателей.
g_signal_connect(button,
"clicked", G_CALLBACK(button_clicked), (gpointer)data);
Ниже показан
код функции с именем button_clicked:
gboolean
button_clicked(GtkWidget* widget, gpointer data) {
gpointer* data_t =
(gpointer*)data;
GtkWidget *label =
(GtkWidget*)data_t[0];
GtkWidget *entry =
(GtkWidget*)data_t[1];
GtkWidget *window =
(GtkWidget*)data_t[2];
const gchar *str =
gtk_entry_get_text(GTK_ENTRY(entry));
if
(get_string_length(str) == 0) {
my_modal_dialog(GTK_WINDOW(window),
"The text is empty. Try again.");
gtk_widget_grab_focus(entry);
return FALSE;
}
if
(get_string_length(str) > 10) {
my_modal_dialog(GTK_WINDOW(window),
"The text of 10 characters. Try again.");
gtk_entry_set_text(GTK_ENTRY(entry),
"");
gtk_widget_grab_focus(entry);
return FALSE;
}
gtk_label_set_text(GTK_LABEL(label),
str);
return TRUE;
}
Рассмотрим
данную функцию подробней:
1) Функция
button_clicked возвращает булево значение,
в качестве параметра передает указатель
на виджет который вызвал данную функцию,
в данном случае виджет с именем button.
Второй параметр это массив указателей
на виджеты.
2) Показанными
ниже строчками мы получаем указатели
на виджеты главного окна, метку текста
и поля редактирования.
gpointer* data_t =
(gpointer*)data;
GtkWidget *label =
(GtkWidget*)data_t[0];
GtkWidget *entry =
(GtkWidget*)data_t[1];
GtkWidget *window =
(GtkWidget*)data_t[2];
3) Следующей
строчкой мы получаем строку текста из
поля редактирования:
const gchar *str =
gtk_entry_get_text(GTK_ENTRY(entry));
4) Далее мы
проверяем полученную строку пуста ли
она, если пуста, то выводим сообщение,
устанавливаем фокус ввода в поле
редактирования и возвращаем FALSE из
функции button_clicked:
if
(get_string_length(str) == 0) {
my_modal_dialog(GTK_WINDOW(window),
"The text is empty. Try again.");
gtk_widget_grab_focus(entry);
return FALSE;
}
5) Дальше проверим
превышает ли введенная строка 10-ти
символов, если превышает, то выводим
сообщение, очищаем поле редактирования,
устанавливаем фокус на поле редактирования
и возвращаем FALSE из функции
button_clicked:
if
(get_string_length(str) > 10) {
my_modal_dialog(GTK_WINDOW(window),
"The text of 10 characters. Try again.");
gtk_entry_set_text(GTK_ENTRY(entry),
"");
gtk_widget_grab_focus(entry);
return FALSE;
}
6) Если все
проверки пройдены успешно, то устанавливаем
текст метке.
gtk_label_set_text(GTK_LABEL(label),
str);
7) По окончанию
работы функция button_clicked возвращает
булево значение TRUE.
Ниже размещены
изображения работы программы:
Рисунок
1. Сообщение, если поле редактирования
пустое
Рисунок
2. Сообщение, если введено больше десяти
символов
Рисунок
3. Правильно введенный текст
Ниже
показан код всей программы:
#include <gtk/gtk.h> #include <string.h> void my_modal_dialog(GtkWindow* parent, gchar* str) { GtkWidget* modal_dialog = gtk_message_dialog_new(parent, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, str); gtk_dialog_run(GTK_DIALOG(modal_dialog)); gtk_widget_destroy(modal_dialog); } gint get_string_length(const gchar *str) { return strlen(str); } gboolean button_clicked(GtkWidget* widget, gpointer data) { gpointer* data_t = (gpointer*)data; GtkWidget *label = (GtkWidget*)data_t[0]; GtkWidget *entry = (GtkWidget*)data_t[1]; GtkWidget *window = (GtkWidget*)data_t[2]; const gchar *str = gtk_entry_get_text(GTK_ENTRY(entry)); if (get_string_length(str) == 0) { my_modal_dialog(GTK_WINDOW(window),
"The text is empty. Try again."); gtk_widget_grab_focus(entry); return FALSE; } if (get_string_length(str) > 10) { my_modal_dialog(GTK_WINDOW(window),
"The text of 10 characters. Try again."); gtk_entry_set_text(GTK_ENTRY(entry), ""); gtk_widget_grab_focus(entry); return FALSE; } gtk_label_set_text(GTK_LABEL(label), str); return TRUE; } int main(int argc, char **argv) { GtkWidget *window = NULL; GtkWidget *grid = NULL; GtkWidget *entry = NULL; GtkWidget *button = NULL; GtkWidget *label = NULL; gpointer data[3]; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Gtk_p4"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 200, 200); gtk_container_set_border_width (GTK_CONTAINER (window), 10); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); grid = gtk_grid_new(); gtk_grid_set_row_spacing (GTK_GRID(grid), 10); gtk_grid_set_column_spacing (GTK_GRID(grid), 10); gtk_container_add (GTK_CONTAINER (window), grid); entry = gtk_entry_new(); gtk_grid_attach(GTK_GRID(grid), entry, 0, 0, 1, 1); label = gtk_label_new("Some text"); gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 2, 1); button = gtk_button_new_with_label("Set text"); gtk_grid_attach(GTK_GRID(grid), button, 1, 0, 1, 1); data[0] = (gpointer)label; data[1] = (gpointer)entry; data[2] = (gpointer)window; g_signal_connect(button, "clicked", G_CALLBACK(button_clicked),
(gpointer)data); gtk_widget_show_all(window); gtk_main(); return 0; }
syntax highlighted by Code2HTML, v. 0.9.1
Комментариев нет:
Отправить комментарий