6. Глава 18: Элементы Пользовательского Ввода
В этой главе мы сосредоточимся на ключевых элементах пользовательского ввода в GTK, которые позволяют вашему приложению получать информацию от пользователя. Мы рассмотрим три основных виджета:
- doc:
GtkEntry <https://docs.gtk.org/gtk3/class.Entry.html> — однострочное текстовое поле для ввода текста.
- doc:
GtkSpinButton <https://docs.gtk.org/gtk3/class.SpinButton.html> — числовой спиннер для ввода чисел в заданном диапазоне.
- doc:
GtkCheckButton <https://docs.gtk.org/gtk3/class.CheckButton.html> — чекбокс (флажок) для переключения логических состояний (включено/выключено).
Эти виджеты являются основой для создания интерактивных форм, настроек и других элементов управления, где требуется получить данные от пользователя.
—
6.1. GtkEntry: Однострочное Текстовое Поле
GtkEntry — это универсальный виджет для ввода и отображения однострочного текста. Он широко используется для полей ввода имени пользователя, пароля, пути к файлу, поисковых запросов и других текстовых данных.
### Основные функции и свойства GtkEntry:
gtk_entry_new()
: Создаёт новый пустой GtkEntry.gtk_entry_new_with_buffer(GtkEntryBuffer *buffer)
: Создаёт GtkEntry с привязанным буфером, что даёт больше контроля над текстом.gtk_entry_set_text(GtkEntry *entry, const gchar *text)
: Устанавливает текст в поле ввода.gtk_entry_get_text(GtkEntry *entry)
: Получает текущий текст из поля ввода. Возвращаемая строка принадлежит виджету, её не нужно освобождать, но она станет недействительной после изменения текста.gtk_entry_set_visibility(GtkEntry *entry, gboolean visible)
: Управляет видимостью текста (например, для полей пароля). FALSE скрывает текст, отображая символы-заполнители.gtk_entry_set_placeholder_text(GtkEntry *entry, const gchar *text)
: Устанавливает текст-подсказку, который отображается, когда поле пустое и не в фокусе.
### Сигналы GtkEntry:
"changed"
: Испускается при любом изменении текста в поле ввода."activate"
: Испускается, когда пользователь нажимает Enter в поле ввода (часто используется для подтверждения ввода).
—
6.4. Обработка Событий: Общие Принципы
Для всех этих виджетов, как и для GtkButton, основным механизмом взаимодействия является система сигналов и слотов (callbacks). Вы подключаете (g_signal_connect
) свои функции-обработчики (callbacks
) к определённым сигналам, которые испускают виджеты при определённых действиях пользователя.
Пример подключения сигналов:
g_signal_connect(entry, "changed", G_CALLBACK(on_entry_changed), NULL);
g_signal_connect(spin, "value-changed", G_CALLBACK(on_spin_changed), NULL);
g_signal_connect(check, "toggled", G_CALLBACK(on_check_toggled), NULL);
—
### Пример 18.1: Окно с текстовым полем, спиннером и чекбоксом
Название исходного файла: input_widgets_example.c
Эта программа демонстрирует создание окна с тремя описанными выше элементами ввода. Все они размещены вертикально с помощью GtkBox, а их изменения отслеживаются через соответствующие callback-функции, выводящие информацию в консоль.
#include <gtk/gtk.h> // Подключаем основную библиотеку GTK.
/**
* @brief Обработчик сигнала "changed" для GtkEntry.
* Вызывается каждый раз при изменении текста в GtkEntry.
* @param entry Указатель на GtkEntry, который испустил сигнал.
* @param user_data Пользовательские данные (в данном случае NULL).
*/
void on_entry_changed(GtkEntry *entry, gpointer user_data) {
// Получаем текущий текст из поля ввода.
const gchar *text = gtk_entry_get_text(entry);
g_print("Entry changed: %s\n", text);
}
/**
* @brief Обработчик сигнала "value-changed" для GtkSpinButton.
* Вызывается каждый раз при изменении числового значения в GtkSpinButton.
* @param spin Указатель на GtkSpinButton, который испустил сигнал.
* @param user_data Пользовательские данные (в данном случае NULL).
*/
void on_spin_changed(GtkSpinButton *spin, gpointer user_data) {
// Получаем текущее значение спиннера как целое число.
gint value = gtk_spin_button_get_value_as_int(spin);
g_print("Spin value: %d\n", value);
}
/**
* @brief Обработчик сигнала "toggled" для GtkCheckButton.
* Вызывается каждый раз при изменении состояния чекбокса (отмечен/не отмечен).
* @param check Указатель на GtkToggleButton (базовый класс для GtkCheckButton),
* который испустил сигнал.
* @param user_data Пользовательские данные (в данном случае NULL).
*/
void on_check_toggled(GtkToggleButton *check, gpointer user_data) {
// Проверяем, активно ли (отмечено) состояние чекбокса.
gboolean active = gtk_toggle_button_get_active(check);
g_print("Check toggled: %s\n", active ? "ON" : "OFF"); // Выводим "ON" или "OFF"
}
/**
* @brief Главная функция программы, точка входа.
* Инициализирует GTK, создает окно, добавляет в него элементы ввода
* и запускает главный цикл событий GTK.
* @param argc Количество аргументов командной строки.
* @param argv Массив строк аргументов командной строки.
* @return Код завершения программы.
*/
int main(int argc, char *argv[]) {
// Инициализация GTK. Всегда вызывается первой.
gtk_init(&argc, &argv);
// 1. Создание главного окна приложения.
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Пример Полей Ввода");
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
// Подключение сигнала "destroy" для корректного завершения приложения.
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
// 2. Создание вертикального контейнера GtkBox.
// Используем GtkBox для размещения всех виджетов вертикально,
// с отступом в 10 пикселей между ними.
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
// Добавляем GtkBox в главное окно.
gtk_container_add(GTK_CONTAINER(window), vbox);
// 3. Создание GtkEntry (текстового поля).
GtkWidget *entry = gtk_entry_new();
// Устанавливаем текст-заполнитель, который виден, когда поле пустое.
gtk_entry_set_placeholder_text(GTK_ENTRY(entry), "Введите ваше имя...");
// Добавляем GtkEntry в вертикальный GtkBox.
gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
// Подключаем обработчик на изменение текста.
g_signal_connect(entry, "changed", G_CALLBACK(on_entry_changed), NULL);
// 4. Создание GtkSpinButton (числового спиннера).
// Сначала создаем объект GtkAdjustment, который определяет диапазон и шаг.
// (начальное значение, нижний предел, верхний предел, шаг при клике, шаг при PageUp/Down, размер страницы)
GtkAdjustment *adj = gtk_adjustment_new(0, 0, 100, 1, 10, 0);
// Создаем спиннер, привязывая его к созданному GtkAdjustment.
// 1.0 - скорость "взбирания" при удержании кнопки, 0 - количество знаков после запятой (целые числа).
GtkWidget *spin = gtk_spin_button_new(adj, 1.0, 0);
// Добавляем спиннер в вертикальный GtkBox.
gtk_box_pack_start(GTK_BOX(vbox), spin, FALSE, FALSE, 0);
// Подключаем обработчик на изменение значения.
g_signal_connect(spin, "value-changed", G_CALLBACK(on_spin_changed), NULL);
// 5. Создание GtkCheckButton (флажка/чекбокса).
GtkWidget *check = gtk_check_button_new_with_label("Я согласен с условиями");
// Устанавливаем начальное состояние чекбокса (например, изначально не отмечен).
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
// Добавляем чекбокс в вертикальный GtkBox.
gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0);
// Подключаем обработчик на изменение состояния.
g_signal_connect(check, "toggled", G_CALLBACK(on_check_toggled), NULL);
// 6. Отображение всех виджетов в окне.
gtk_widget_show_all(window);
// 7. Запуск главного цикла событий GTK.
// Приложение будет ждать действий пользователя, пока не будет закрыто.
gtk_main();
return 0; // Возвращаем код успешного завершения.
}
—
6.5. Компиляция и Запуск
Сохраните код выше в файл с именем input_widgets_example.c.
### Компиляция:
Для сборки программы используйте следующую команду в терминале, находясь в директории с исходным файлом:
gcc input_widgets_example.c -o input_widgets_example `pkg-config --cflags --libs gtk+-3.0`
### Запуск:
После успешной компиляции вы можете запустить ваше приложение:
./input_widgets_example
—
6.6. Ожидаемый результат
При запуске программы вы увидите окно с заголовком «Пример Полей Ввода». Внутри окна будут расположены вертикально следующие элементы:
Текстовое поле (`GtkEntry`): Будет отображаться текст-подсказка «Введите ваше имя…». При вводе текста, каждое изменение символа будет выводиться в консоль.
Числовой спиннер (`GtkSpinButton`): Будет показывать числовое значение (изначально 0), которое можно изменять с помощью стрелок вверх/вниз или вводя число вручную. Каждое изменение значения будет выводиться в консоль.
Чекбокс (`GtkCheckButton`): Рядом с ним будет метка «Я согласен с условиями». Изначально чекбокс будет не отмечен. При клике на него, его состояние будет меняться между «ON» и «OFF», и это изменение будет выводиться в консоль.
—
6.7. Дополнительные материалы
GtkEntry: Официальная документация GtkEntry.
GtkSpinButton: Официальная документация GtkSpinButton.
GtkCheckButton: Официальная документация GtkCheckButton.
GtkAdjustment: Официальная документация GtkAdjustment.
C_GUI_Handbook GitHub - Репозиторий с примерами кода из этого руководства.
—
6.8. Навигация
- doc:
Глава 17: Гибкая Компоновка с GtkGrid <chapter17>
- doc:
Глава 19: Выпадающие списки и радиокнопки <chapter19>