Текст книги "Основы программирования в Linux"
Автор книги: Нейл Мэтью
Соавторы: Ричард Стоунс
Жанры:
Программирование
,сообщить о нарушении
Текущая страница: 58 (всего у книги 67 страниц)
Введение в систему X
Если вы когда-либо применяли оконную систему рабочего стола в ОС Linux, скорее всего вы использовали графическую систему X с открытым программным кодом. Одна из наиболее передовых и в результате разочаровывающих характеристик X – жесткая привязка к идеологии «инструментов, а не политики». Это означает, что в системе X нет определения какого-либо пользовательского интерфейса, но есть средства для его создания. Вы вольны создавать целиком собственную среду рабочего стола, экспериментируя и вводя новшества при желании. Но это же свойство долгое время тормозило разработку пользовательских интерфейсов в системах Linux и UNIX. Для заполнения этой пустоты возникли два проекта рабочего стола, предпочитаемые пользователями Linux: GNOME и KDE. Рабочий стол ОС Linux, тем не менее, не ограничивается системой X. В действительности рабочий стол в Linux – это довольно расплывчатая субстанция без определенной версии, выпущенной в рамках одного проекта или какой-либо группой специалистов. Современная установка содержит мириады библиотек, утилит и приложений, которые все вместе называются «рабочим столом».
У системы X, первоначально разработанной в MIT (Массачусетский технологический институт) в начале 1980 гг., длинная и яркая история. Она создавалась как унифицированная оконная система для высокопроизводительных рабочих станций того времени, которые были очень дорогими перемалывающими огромные объемы чисел чудовищами.
Когда наступили 1990 гг. и цены на оборудование упали, энтузиасты перенесли систему X на недорогие домашние компьютеры PC, этот проект стал называться XFree86 (процессоры PC, выпускавшиеся корпорацией Intel и другими компаниями, были известны как процессоры x86), и сегодня вместе с системой Linux распространяются потомки проекта XFree86, а в большинстве дистрибутивов Linux применяется вариант системы X, названный X.Org,
X Window System разделена на компоненты аппаратного и программного уровней, называемые Х-сервером и Х-клиентом. Эти компоненты взаимодействуют с помощью протокола с легко угадываемым названием "X-протокол". В следующих разделах рассматривается по очереди каждый из этих компонентов.
X-серверX-сервер запускается на пользовательской локальной машине и выполняет низкоуровневые операции прорисовки графического экрана. Присутствие в названии слова «сервер» часто смущает: X-сервер выполняется на вашем настольном ПК. X-клиенты могут запускаться на вашем настольном ПК или на самом деле выполняться на других компьютерах в вашей сети, включая серверы. Если подумать, обратная терминология не лишена смысла, но часто кажется применяемой задом наперед.
Поскольку X-сервер напрямую общается с видеокартой, вы должны применять X-сервер, соответствующий вашей видеокарте, и для него следует задавать подходящее разрешение, скорость обновления экрана, количество цветов и т.д. Файл конфигурации называется xorg.conf или Xfree86Config. В прошлом вы обычно должны были вручную редактировать файл конфигурации, чтобы добиться корректной работы системы X. К счастью, современные дистрибутивы Linux автоматически определяют нужные установочные параметры, экономя время пользователя и избавляя его от решения головоломок!
X-сервер ждет ввод пользователя от мыши и клавиатуры и передает нажатия клавиш и щелчки кнопками мыши приложениям, X-клиентам. Эти сообщения называют событиями; они служат основными элементами программирования GUI. Позже в этой главе мы подробно рассмотрим события и их логическое расширение GTK+ сигналы.
X-клиентX-клиент – это любая программа, использующая X Window System как GUI. Примерами могут служить xterm, xcalc и более сложные, приложения, например, Abiword. X-клиент ждет события пользователя, посылаемые X-сервером, и отвечает на них отправкой обратно серверу сообщений об обновлении изображений.
X-протоколПримечание
X-клиент необязательно должен быть на той же машине, что и X-сервер.
X-клиент и X-сервер взаимодействуют с помощью X-протокола, который позволяет клиенту и серверу быть разделенными сетью. Например, вы можете запустить приложение X-клиент с удаленного компьютера через Интернет или шифруемую виртуальную частную сеть (Virtual Private Network, VPN). В большинстве персональных систем Linux X-клиенты и X-сервер работают в одной и той же системе.
XlibXlib – это библиотека, неявно используемая X-клиентом для генерации сообщений X-протокола. Она предоставляет API очень низкого уровня, позволяющий клиенту отображать простейшие элементы на X-сервере и откликаться на простейший ввод. Мы должны подчеркнуть, что Xlib – это библиотека очень низкого уровня, и создание с ее применением даже чего-либо столь же простого, как меню, – невероятно трудоемкий процесс, требующий сотен строк программного кода.
Разработчик GUI не может эффективно программировать непосредственно с помощью Xlib. Вам нужен API, делающий легким и простым создание таких элементов GUI, как меню, кнопки и раскрывающиеся списки. Говоря кратко, эту роль играет комплект инструментальных средств или элементов интерфейса.
Комплекты инструментовКомплект инструментов или элементов интерфейса – это библиотека GUI, которую X-клиенты применяют для значительного упрощения создания окон, меню, кнопок и т.п. С помощью комплекта инструментальных средств вы можете создавать кнопки, меню, фреймы и тому подобное с помощью вызовов одной функции. Общий термин для обозначения элементов GUI, подобных перечисленным, – виджеты, универсальный элемент, который вы найдете во всех современных библиотеках GUI.
Существует масса комплектов инструментов для системы X, из которых вы можете выбирать, и каждый из них обладает определенными достоинствами и недостатками. На каком остановиться – важное проектное решение для вашего приложения, и при выборе следует учитывать следующие факторы.
□ Для кого предназначено ваше приложение?
□ Будут ли установлены библиотеки комплекта инструментов у ваших пользователей?
□ Перенесен ли комплект инструментов в другие популярные операционные системы?
□ Какой лицензией программного обеспечения пользуется комплект инструментов и согласуется ли она с предполагаемым вами использованием?
□ Поддерживает ли комплект инструментов ваш язык программирования?
□ Современный ли внешний вид и реализация у комплекта инструментов?
На протяжении многих лет самыми популярными комплектами инструментальных средств были Motif, OpenLook и Xt, но они уступили технически более совершенным комплектам GTK+ и Qt, формирующим основу рабочих столов GNOME и KDE соответственно.
Оконные менеджерыПоследний компонент X-мозаики – оконный менеджер или диспетчер, который отвечает за расположение окон на экране. Оконные менеджеры часто поддерживают отдельные «рабочие области», на которые делится рабочий стол, увеличивая область экрана, с которой вы можете взаимодействовать. Оконный менеджер также отвечает за графическое оформление всех окон, состоящее, как правило, из рамки и полосы заголовка с пиктограммами максимизации, минимизации и закрытия окна. Оконные менеджеры обеспечивают частично внешний вид рабочего стола, например заголовки окон.
К широко распространенным относятся следующие оконные менеджеры:
□ Metacity – оконный менеджер, используемый по умолчанию для рабочего стола GNOME;
□ KWin – оконный менеджер, применяемый по умолчанию для рабочего стола KDE;
□ Openbox – разработанный для экономии ресурсов и запускаемый на более старых и медленных системах;
□ Enlightenment – оконный менеджер, отображающий превосходную графику и спецэффекты.
Как и все в системе X, оконные менеджеры можно переключать. Тем не менее, большинство пользователей запускает оконный менеджер, входящий в их поставку среды рабочего стола.
Другие способы создания GUI – платформно-независимые оконные APIСледует упомянуть и другие способы создания GUI, характерные для ОС Linux, – существуют языки с собственной поддержкой GUI, функционирующей под управлением Linux.
□ Язык Java поддерживает программирование GUI с помощью Swing и более старых API AWT. Внешнее оформление GUI на языке Java понравится не всем и на более старых машинах интерфейс может восприниматься как громоздкий и медленно реагирующий. Огромное преимущество Java заключается в том, что единожды откомпилированный код на языке Java выполняется неизменным да любой платформе с виртуальной машиной Java (Java Virtual Machine), которая включает Linux, Windows, Mac OS и мобильные устройства. Дополнительную информацию см. на Web-сайте http://java.sun.com.
□ Язык программирования C# очень похож на язык Java. В систему Linux общеязыковая исполняющая среда (C# Common Language или CLR) пришла из проекта Mono, см. Web-сайт http://www.mono-project.com. C# на платформе Mono поддерживает модель программирования Windows Forms, применяемую в Windows, и специальную привязку к комплекту инструментов GTK+, названную Gtk#.
□ Tcl/Tk – язык сценариев, отлично подходящий для быстрой разработки интерфейсов GUI и работающий с X, Windows и Mac OS. Он очень удобен для быстрого макетирования или маленьких утилит, нуждающихся в простоте и удобстве сопровождения сценария. Все подробности можно найти на Web-сайте http://tcl.tk.
□ Python – тоже язык сценариев. Вы можете применять Tk, часть Tcl/Tk, из Python или программировать в привязке Python к GTK+, разрабатывая программы GTK+ на языке Python. Дополнительную информацию о языке Python см. на Web-сайте http://www.python.org.
□ Perl – еще один популярный язык сценариев в Linux. Вы можете применять Tk, часть Tcl/Tk, в языке Perl как Perl/Tk. Дополнительную информацию о Perl см. на Web-сайте http://www.perl.org/.
За платформою независимость, которую приносят эти языки, приходится платить. Совместное использование данных их собственными приложениями – например, применение операции перетаскивания мышью (drag and drop) – затруднено, и сохранение конфигурации обычно следует выполнять специфическим, а не стандартным способом, характерным для рабочего стола. Иногда поставщики программного обеспечения на языке Java хитрят, включая в поставку платформно-зависимые расширения для того, чтобы избежать подобных проблем.
Введение в GTK+
Теперь, когда вы познакомились с системой X Window System, самое время рассмотреть комплект инструментальных средств GTK+ Toolkit. GTK+ появился на свет как часть популярного графического редактора GNU Image Manipulation Program (GIMP), от которого он и унаследовал свое имя (The Gimp ToolKit). Очевидно, что программисты GIMP всерьез предвидели превращение GTK+ в самостоятельный проект, поскольку он вырос и стал одним из самых мощных и популярных комплектов инструментов. Домашнюю страницу проекта GTK+ можно найти по адресу http://www.gtk.org.
Примечание
В итоге, GTK+ – это библиотека, которая существенно упрощает создание графических интерфейсов пользователей (Graphical User Interface, GUI), предоставляя набор готовых компонентов, именуемых виджетами, которые вы соединяете вместе с помощью легких в использовании вызовов функций, включенных в логическую структуру вашего приложения.
Несмотря на то, что GTK+ – это проект GNU, как и GIMP, он выпущен на условиях более либеральной лицензии (Lesser General Public License, Стандартная общественная лицензия ограниченного применения GNU), которая освобождает программное обеспечение (включая патентованное программное обеспечение с закрытым программным кодом), написанное с использованием GTK+, от уплаты лицензионных вознаграждений или авторских гонораров, а также других ограничений. Свобода, предлагаемая лицензией GTK+, отличает этот комплект инструментов от его конкурента Qt (который будет обсуждаться в следующей главе), чья лицензия GPL запрещает разработку коммерческого программного обеспечения с использованием Qt (в этом случае вы должны купить коммерческую лицензию для Qt).
Комплект GTK+ целиком написан на языке С и большая часть программного обеспечения GTK+ также написана на С. К счастью, существует ряд привязок к языкам (language binding), позволяющих применять GTK+ в предпочитаемом вами языке программирования, будь то С++, Python, PHP, Ruby, Perl, C# или Java.
Комплект GTK+ сформирован как надстройка для ряда других библиотек, К ним относятся следующие:
□ GLib – предоставляет низкоуровневые структуры данных, типы, поддержку потоков, циклов событий и динамической загрузки;
□ GObject – реализует объектно-ориентированную систему на языке С, не требующую применения языка С++;
□ Pango – поддерживает визуализацию и форматирование текста;
□ ATK – помогает создавать приложения с доступом и позволяет пользователям запускать ваши приложения с помощью средств чтения экрана и других средств доступа;
□ GDK (GIMP Drawing Kit) – обрабатывает визуализацию низкоуровневой графики поверх библиотеки Xlib;
□ GdkPixbuf – помогает манипулировать изображениями в программах GTK+;
□ Xlib – предоставляет низкоуровневую графику в системах Linux и UNIX.
Система типов GLibЕсли вы когда-нибудь просматривали программный код GTK+, то могли удивиться, увидев множество типов данных языка С с префиксом g
, например, gint
, gchar
, gshort
, а также незнакомые типы gint32
и gpointer
. Дело в том, что комплект GTK+ основан на библиотеках переносимости языка С (portability libraries), названных GLib и GObject, которые определяют эти типы для того, чтобы способствовать межплатформным разработкам.
GLib и GObject помогают межплатформным разработкам, обеспечивая стандартный набор типов данных замещения, функций и макросов для поддержки управления памятью и общих задач. Эти типы, функции и макросы означают, что, как программисты GTK+, мы можем быть уверены в том, что наш программный код надежно переносится на другие платформы и архитектуры.
В библиотеке Glib также определено несколько очень удобных констант:
#include
#define FALSE 0
#define TRUE !FALSE
Дополнительные типы данных – это типы, служащие заменой для стандартных типов данных C (из соображений совместимости и читабельности) и гарантирующие одинаковый размер в байтах на. всех платформах:
□ gint
, guint
, gchar
, guchar
, glong
, gulong
, gfloat
и gdouble
– просто замены для стандартных типов С для совместимости;
□ gpointer
– синоним типа (void*
);
□ gboolean
– полезен для представления логических значений и служит оболочкой для int
;
□ gint8
, guint8
, gint16
, guint16
, gint32
и guint32
– знаковые и беззнаковые типы с гарантированным размером в байтах.
Удобно то, что применение библиотек GLib и GObject почти прозрачно. Glib широко используется в GTK+, поэтому если у вас есть работающая установка GTK+, то вы обнаружите, что библиотека Glib уже установлена. Как вы увидите позже в этой главе, при программировании с помощью комплекта GTK+ вам даже не придется явно включать заголовочный файл glib.h.
Система объектов GTK+Все, у кого уже есть опыт программирования GUI, возможно, поймут наше утверждение о строгой приверженности библиотек GUI концепции объектно-ориентированного программирования (ООП), настолько строгой, что все современные комплекты инструментов, включая GTK+, написаны в стиле объектно-ориентированного программирования.
Несмотря на то, что комплект инструментов GTK+ написан на чистом С, он поддерживает объекты и ООП благодаря библиотеке GObject. Эта библиотека поддерживает наследование объектов и полиморфизм с помощью макросов.
Давайте рассмотрим образец наследования и полиморфизма на примере иерархии объектов GtkWindow, взятой из документации GTK+ API.
GObject
+–GInitiallyUnowned
+–GtkObject
+–GtkWidget
+–GtkContainer
+–GtkBin
+–GtkWindow
Этот список объектов говорит о том, что объект GtkWindow
– потомок GtkBin
, и, следовательно, любую функцию, которую вы вызываете с объектом GtkBin
, вы можете вызвать и с объектом GtkWindow
. Точно так же объект GtkWindow
наследует из объекта GtkContainer
, который в свою очередь наследует из объекта GtkWidget
.
Для удобства все функции создания виджетов возвращают тип GtkWidget
. Например,
GtkWidget* gtk_window_new(GtkWindowType type);
Предположим, что вы создаете объект GtkWindow
и хотите передать возвращенное значение в функцию, ожидающую объект типа GtkContainer
, например, такую, как gtk_container_add
:
void gtk_container_add(GtkContainer* container, GtkWidget *widget);
Вы применяете макрос GTK_CONTAINER
для приведения типов GtkWidget
и GtkContainer
:
GtkWidget * window = gtk_window_new(GTK GTK_WINDOW_TOPLEVEL);
gtk_container_add(GTK_CONTAINER(window), awidget);
Назначение этих функций вы узнаете позже; сейчас просто отметьте для себя частое применение макросов. Для каждого возможного приведения типа существует макрос.
Знакомство с GNOMEПримечание
Не беспокойтесь, если вам все это не очень понятно; вам не нужно разбираться в подробностях ООП для того, чтобы освоить GNOME/GTK+. На самом деле это безболезненный способ усвоить идеи и преимущества ООП на базе знакомого вам языка С.
GNOME – имя, данное проекту, начатому в 1997 г. программистами, работавшими в проекте GNU Image Manipulation Program (GIMP) над созданием унифицированного рабочего стола для Linux. Все были согласны с тем, что выбор ОС Linux как платформы рабочего стола тормозился отсутствием согласованной стратегии. В то время рабочий стол Linux напоминал Дикий Запад без общих стандартов или выработанных на практике приемов, и программисты могли делать все, что вздумается. Без сводной группы, контролирующей меню рабочего стола, согласованное представление и отображение, документацию, трансляцию и т.д., освоение рабочего стола новичком было в лучшем случае путанным, а в худшем – непригодным.
Группа GNOME намеревалась создать рабочий стол для ОС Linux с лицензией GPL, разрабатывая утилиты и программы настройки в едином согласованном стиле, одновременно способствуя развитию стандартов для взаимодействия приложений, печати, управления сеансами и лучших приемов в программировании GUI приложений.
Результаты их стараний очевидны: среда GNOME – основа стандартного рабочего стола Linux в дистрибутивах Fedora, Red Hat, Ubuntu, openSUSE и др. (рис. 16.1).
Первоначально название GNOME означало GNU Network Object Model Environment (среда сетевых объектных моделей GNU), что отражает одну из ранее поставленных задач, внедрение в систему Linux объектной интегрированной системы, такой как Microsoft OLE, для того, чтобы вы могли, например, встроить электронную таблицу в документ текстового процессора. Теперь поставлены новые задачи, и то, что сегодня нам известно как GNOME, – это законченная среда рабочего стола, содержащая панель для запуска приложений, комплект программ и утилит, библиотеки программирования и средства поддержки разработчиков.
Перед тем как начать программировать, следует убедиться в том, что все библиотеки установлены.
Рис. 16.1
Установка библиотек разработки GNOME/GTK+Полный рабочий стол GNOME со своими стандартными приложениями и библиотеками разработки GNOME/GTK+ включает в себя более 60 пакетов, поэтому установка GNOME с нуля вручную или из исходного кода – устрашающая перспектива. К счастью, в современных дистрибутивах Linux есть отличные утилиты управления пакетами, превращающие установку GNOME/GTK+ и библиотек разработки в пустяковое дело.
В дистрибутивах Linux Red Hat и Fedora вы открываете средство Package Management (Управление пакетами), щелкнув мышью кнопку меню Applications (Приложения) и выбрав команду Add/Remove Software (Добавить/удалить программы). Когда появится Package Management (рис. 16.2), убедитесь в том, что установлен флажок GNOME Software Development (Разработка программ GNOME). Загляните в область Development (Разработка) для этого установочного параметра.
В этой главе вы будете работать с GNOME/GTK+ 2, поэтому убедитесь в том, что установлены библиотеки версии 2.x.Рис. 16.2
В случае дистрибутивов, применяющих RPM-пакеты, у вас должны быть установлены как минимум следующие RPM-пакеты:
□ gtk2-2.10.11-7.fc7.rpm;
□ gtk2-devel-2.10.11-7.fc7.rpm;
□ gtk2-engines-2.10.0-3.fc7.rpm;
□ libgnome-2.18.0-4.fc7.rpm;
□ libgnomeui-2.18.l-2.fc7.rpm;
□ libgnome-devel-2.18.0-4.fc7.rpm;
□ libgnomeui-devel-2.18.1-2.fc7.rpm.
Примечание
В этом примере комбинация символов fc7 указывает на дистрибутив Linux Fedora 7. В вашей системе могут быть слегка отличающиеся имена.
В дистрибутиве Debian и основанных на Debian системах, таких как Ubuntu, вы можете использовать программу apt-get для установки пакетов GNOME/GTK+ с разных сайтов-зеркал (mirrors). Для выяснения подробностей следуйте по ссылкам Web-сайта http://www.gnome.org.
Опробуйте также демонстрационное приложение GTK+, в котором показаны все виджеты и их оформление (рис. 16.3).
$ gtk-demo
Рис. 16.3
Примечание
Для каждого виджета отображаются вкладки Info (Информация) и Source (Исходный код). На вкладке Source (Исходный код) приведен программный код на языке С для применения данного виджета. На ней может быть представлено множество примеров.
Выполните упражнение 16.1.
Упражнение 16.1. Обычное окно GtkWindow
Давайте начнем программирование средствами GTK+ с простейшей из программ GUI – отображения окна. Вы увидите библиотеки GTK+ в действии и большой набор функциональных возможностей, получаемых из очень короткого программного кода.
1. Введите программу и назовите ее gtk1.с:
#include
int main(int argc, char *argv[]) {
GtkWidget *window;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show(window);
gtk_main();
return 0;
}
2. Для компиляции gtk1.c введите следующую команду:
$ gcc gtk1.c -о gtk1 `pkg-config –cflags –libs gtk+-2.0`
Примечание
Будьте внимательны и набирайте обратные апострофы, а не обычные апострофы – помните о том, что обратные апострофы – это инструкции, заставляющие оболочку выполнить заключенную в них команду и добавить ее вывод в конец строки.
Когда вы выполните программу с помощью следующей команды, ваше окно должно раскрыться (рис. 16.4).
$ ./gtk1
Рис. 16.4
Учтите, что вы можете перемещать окно, изменять его размер, сворачивать и раскрывать его на весь экран.
Как это работает
Включить заголовочные файлы, необходимые для библиотек GTK+ и связанных с ними библиотек, можно с помощью одного оператора #include
. Далее вы объявляете окно как указатель на объект GtkWidget
.
Затем для инициализации библиотек GTK+ следует выполнить вызов gtk_init
, передав аргументы командной строки argc
и argv
. Это дает возможность GTK+ выполнить синтаксический анализ любых параметров командной строки, о которых комплект должен знать. Учтите, что вы всегда должны инициализировать GTK+ таким способом перед вызовом любых функций GTK+.
Суть примера заключается в вызове функции gtk_window_new
. Далее приведен ее прототип:
GtkWidget* gtk_window_new(GtkWindowType type);
Параметр type может принимать в зависимости от назначения окна одно из двух значений:
□ GTK_WINDOW_TOPLEVEL
– стандартное окно с рамкой;
□ GTK_WINDOW_POPUP
– окно без рамки, подходящее для диалогового окна.
Почти всегда вы будете применять значение GTK_WINDOW_TOPLEVEL
, потому что для создания диалоговых окон, как вы узнаете позже, есть гораздо более удобные способы.
Вызов gtk_window_new
создает окно в памяти, таким образом у вас появляется возможность перед реальным выводом окна на экран заполнить его виджетами, изменить размер окна, его заголовок и т.д. Для того чтобы окно появилось на экране, выполните вызов функции gtk_widget_show
:
gtk_widget_show(window);
Эта функция принимает указатель типа GtkWidget
, поэтому вы просто предоставляете ссылку на свое окно.
Последним вы выполняете вызов функции gtk_main
. Эта основная функция запускает процесс обмена информацией (interactivity process), передавая управление GTK+, и не возвращает его до тех пор, пока не будет выполнен вызов функции gtk_main_quit
. Как видно в программе gtk1.с, этого никогда не происходит, поэтому приложение не завершается даже после закрытия окна. Проверьте это, щелкнув кнопкой мыши пиктограмму закрытия окна и убедившись в отсутствии строки, приглашающей вводить команду. Вы исправите это поведение после того, как познакомитесь с сигналами и обратными вызовами в следующем разделе. Сейчас завершите приложение, нажав комбинацию клавиш