Шрифт:
Интервал:
Закладка:
Первый параметр — это список, который нужно отсортировать. Второй — это функция сравнения двух элементов. Вот ее прототип:
typedef gint (*GCompareFunc) (gconstpointer a, gconstpointer b); Данную функцию вы должны написать самостоятельно. Она должна принимать два параметра и возвращать целое значение:
♦ если a<b, то -1 (точнее, любое число меньше 0);
♦ если a==b, то 0;
♦ если a>b, то 1 (любое число больше 0).
Библиотека Glib также содержит средства для работы с деревьями — как бинарными, так и произвольными, но мы эти средства рассматривать не будем.
23.2.5. Таймеры в Glib
Библиотека Glib позволяет использовать таймеры в наших программах.
Для этого нужно:
♦ подключить заголовочный файл gtimer.h;
♦ создать таймер функцией GTimer *g_timer_new();
♦ запустить таймер функцией g_timer_start(GTimer *timer);
♦ узнать время, отсчитанное таймером — g_timer_elapsed();
♦ при необходимости перезапустить таймер с помощью функции g_timer_reset(GTimer *timer);
♦ остановить таймер функцией g_timer_stop(GTimer * timer);
♦ уничтожить таймер — g_timer_destroy(GTimer *timer).
Стоит остановиться подробнее лишь на функции g_timer_elapsed(GTimer *timer, gulong *mcs). Данная функция возвращает число секунд, отсчитанное таймером. По адресу указателя *mcs записывается число микросекунд.
Пример использования таймера представлен в листинге 23.1.
Листинг 23.1. Использование таймера
#include <stdio.h>
#include <glib.h>
#include <gtimer.h>
int main() {
double sec;
gulong ms;
int i;
GTimer *timer = g_timer_new();
printf("Данный цикл будет работать не более 10 секундn");
g_timer_start(timer);
for (i=1; i>0;) {
sec = g_timer_elapsed(timer,&ms);
if (sec >=10) {
g_timer_stop(timer);
printf("Таймер остановлен. Мкс: %dn",ms);
break;
}
}
g_timer_destroy(timer);
return 0;
}
23.3. Первая программа на GTK+
23.3.1. Виджиты
Перед написанием самой простой GTK-программы нужно разобраться с терминологией GTK. Элементы графического интерфейса пользователя — окна, кнопки, поля ввода, переключатели и тому подобное — называются виджитами.
Основным элементом графического интерфейса является окно. Виджиты для размещения в окне помещаются в контейнер. В самом окне выравнивать виджиты можно с помощью вертикальных/горизонтальных боксов или же таблиц. Второй способ более гибок, хотя он может показаться вам сложнее.
Виджиты могут реагировать на сигналы, например, щелчок мышью. При этом вызывается функция-обработчик события (сигнала), если вы определили ее.
Работа с виджитами происходит по такой схеме:
1. создание виджита с помощью одной из функций библиотеки GTK;
2. определение свойств виджита;
3. определение сигналов виджита, если он должен реагировать на сигналы;
4. размещение виджита в контейнере, то есть привязка его к окну;
5. отображение виджита.
Нужно обязательно отобразить виджит, иначе его никто не увидит. Например, следующий фрагмент кода создает виджит — кнопку с текстом — и отображает ее.
GtkWidget *button;
...
/* Рисуем кнопочку с надписью Hello, All */
button = gtk_button_new_with_label("Hello, All");
/* При нажатии кнопки будет вызвана функция hello() */
gtk_signal_connect(GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC(hello), NULL);
/* Помещаем кнопку в контейнер */
gtk_container_add(GTK_CONTAINER(window), button);
/* Отображаем кнопку. */
gtk_widget_show(button);
Первый оператор создает кнопку (button), второй — добавляет кнопку в контейнер. В данном случае контейнером является наше окно. Виджит window должен быть создан раньше: нельзя создать кнопку без окна. Точнее, можно, но тогда она не будет привязана к какому-либо окну и мы ее не увидим. Функция gtk_widget_show() отображает нашу кнопку. Не забудьте отобразить и само окно. Порядок отображения виджитов особой роли не играет, но рекомендуется главное окно отображать в последнюю очередь.
23.3.2. Окна
Сейчас мы напишем программу, которая будет формировать небольшое графическое окошко. Начнем сразу с исходного кода — так будет проще понять, что есть что.
Листинг 23.2. Простое окно (файл first.с)
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
GtkWidget *window1;
gtk_init(&argc, &argv);
window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window1), "Заголовок");
gtk_widget_show(window1);
gtk_main();
return 0;
}
Сначала мы подключаем заголовочный файл gtk/gtk.h — это необходимое условие для того, чтобы начать работу с библиотекой GTK. В первой строке программы мы объявляем наш основной (и единственный в этой программе) виджит — виджит основного окна:
GtkWidget *window1;
Обратите внимание, что виджит объявлен, но работать с ним пока нельзя. Сначала (обязательно до вызова первой GTK-функции) нужно вызвать инициализирующую функцию gtk_init() и передать ей два два параметра — аргументы функции main(). После того, как библиотека инициализирована, нужно вызвать функцию gtk_window_new(), которая создает окно (напомню, что пока окно объявлено, но не создано). Теперь, когда виджит окна создан, можно установить его свойства и определить реакцию на сигналы. Установим свойство Title (заголовок) окна. Это делается с помощью функции gtk_window_set_title():
gtk_window_set_title(GTK_WINDOW(window1), "Заголовок");
Теперь можно отобразить наше окно:
gtk_widget_show(window1);
Чтобы наше приложение могло реагировать на события оконной среды (например, щелчок мыши), нужно вызвать функцию gtk_main(). Функции gtk_init() и gtk_main() должны присутствовать в любой GTK-программе.
Теперь откомпилируем наше приложение. Для этого введем следующую команду в командной строке:
$ gcc first.с -о first `gtk-config --cflags` `gtk-config --libs`
Флаги `gtk config --cflags` `gtk-config --libs` нужно использовать при компиляции любой GTK-программы. Если компиляция не удается, то проверьте, что вы используете апострофы (`), а не одинарные кавычки ('), и что программа gtk-config у вас установлена.
Запустим нашу программу в эмуляторе терминала X Window (или оконной среды GNOME/KDE):
$ ./first
Вы увидите окно, изображенное на рис. 23.1.
Рис. 23.1. Простое окно
Теперь закроем окно и перейдем к терминалу: окно закрыто, мы его больше не видим, а терминал не освобожден. Наша программа не реагирует на событие закрытия окна. По идее, когда графическая среда закрывает окно, программа должна завершить свою работу. А наша программа этого не делает. Значит, нужно «научить» ее реагировать на события (сигналы) оконной системы. Для этого нажмите в терминале Ctrl+С и отредактируйте исходный текст программы следующим образом:
Листинг 23.3. Добавим реакцию на закрытие окна
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
GtkWidget *window1;
gtk_init(*argc, &argv);
window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_signal_connect(GTK_OBJECT(window1), "destroy",
GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
gtk_widget_show(window1);
gtk_main();
return 0;
}
Функция gtk_signal_connect() устанавливает реакцию объекта window1 на сигнал destroy и вызывает функцию qtk_main_quit() для завершения работы программы.
А что если нам при завершении работы программы нужно выполнить какие-нибудь специфические действия, например, удалить временные файлы? Тогда нужно написать свою функцию-обработчик события destroy (листинг 23.4).
Эта функция будет называется destroy_window1(), и мы «пропишем» ее в функции gtk_signal_connect() в качестве обработчика события закрытия окна вместо gtk_main_quit(). Делать она не будет ничего, просто вызовет стандартную функцию gtk_main_quit().
Листинг 23.4. Добавляем собственную функцию-обработчик завершения работы
#include <gtk/gtk.h>
void destroy_window1(GtkWidget *widget, gpointer data);
int main(int argc, char *argv[]) {
GtkWidget *window1;
gtk_init(&argc, &argv);
window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_signal_connect(GTK_OBJECT(window1), "destroy",
(GtkSignalFunc)destroy_window1, &window1);
gtk_widget_show(window1);
gtk_main();
return(0);
}
void destroy_window1(GtkWidget *widget, gpointer data) {
gtk_main_quit();
}
23.3.3. Изменение размеров окна
Вам кажется, что окно слишком маленькое и не подходит для нашей программы? Для изменения размеров окна лучше всего использовать функцию
- Операционная система UNIX - Андрей Робачевский - Программное обеспечение
- Разработка приложений в среде Linux. Второе издание - Майкл Джонсон - Программное обеспечение
- Искусство программирования для Unix - Эрик Реймонд - Программное обеспечение
- Linux - Алексей Стахнов - Программное обеспечение
- Fedora 8 Руководство пользователя - Денис Колисниченко - Программное обеспечение
- Недокументированные и малоизвестные возможности Windows XP - Роман Клименко - Программное обеспечение
- Изучаем Windows Vista. Начали! - Дмитрий Донцов - Программное обеспечение
- Windows Vista - Виталий Леонтьев - Программное обеспечение
- Архитектура операционной системы UNIX - Морис Бах - Программное обеспечение
- Windows Vista. Трюки и эффекты - Юрий Зозуля - Программное обеспечение