GnomeOrgRu : Разработка/МежплатформенныйGTK

Межплатформенные приложения GTK+: взгляд новичка

Исходная статья по адресу: http://www.gnomejournal.org/article/53/cross-platform-gtk-applications-a-newcomers-perspective
4 марта 2007, Джон Рамсдел (John D. Ramsdell)

В своей статье Джон Рамсдел (John D. Ramsdell) рассказывает об опыте разработки межплатформенного приложения GTK+.

Введение

Чтобы отточить свои навыки программирования, я решил написать игру с использованием графического инструментария, с которым я ранее не был знаком, а затем портировать ее на несколько платформ. В качестве графического инструментария я выбрал GIMP Toolkit, а в качестве игры – полпулярную головоломку Судоку, поэтому своё приложение я назвал GTK Sudoku. В этой статье я описал путь, которым я пришел к использованию этого замечательного инструментария.

Требования к графическому инструментарию

При выборе графического инструментария я пользовался четырьмя критериями:
  1. инструментарий должен поддерживать межплатформенную разработку;
  2. инструментарий должен быть одним из тех, которые я не использовал. Это исключает FLTK и WxWidgets;
  3. на мой взгляд С лучше, чем C++;
  4. я хотел, чтобы GTK Sudoku был масштабируем, в плане того, чтобы шрифт, а не размеры экрана, определял размеры окон и виджетов. Конечно, в этом плане векторная графическая библиотека Cairo вне конкуренции.
Решение логической головоломки Sudoku заключается в том, чтобы заполнить цифрами все клетки доски, причем каждая строка, колонка и квадрат 3х3 должны содержать все цифры от 1 до 9. GTK Sudoku позволяет исключить большинство трудностей при решении головоломки. От большинства подобных программ GTK Sudoku отличает то, что пользователь задает правило, которое объясняет каждое изменение на доске Sudoku. Программа не сможет применить правило, если отсутствуют предпосылки его выполнения, это помогает рано обнаруживать ошибки.

Lua, GTK+, Import/Export ... ё моё!

Прежде чем рассказывать об уроках, полученных мной при выполнении этого проекта, немного предыстории. GTK Sudoku создавалась как графическая оболочка консольной программы, написанной на Lua. Lua – это популярный среди разработчиков игр не сложный и легко встраиваемый скриптовый язык. Существует версия интерпретатора Lua в виде отдельного приложения, в котором пользователи могут работать со скриптами в цикле загрузка-выполнение-вывод. Я игрался со своим скриптом Sudoku больше года, однако, кроме меня, не нашлось желающих вводить функции Lua в интерпретатор, чтобы сыграть партию Sudoku. Поэтому, чтобы сделать игру более доступной, я решил сделать к ней графическую оболочку.

Встраивание Lua-скрипта прошло быстро и без проблем. Он естественным образом инкапсулировался в C-модуль, который экспортирует 4 функции и 3 импортирует. Основное изменение в Lua-скрипте заключалось в добавлении справочной системы, которая была просто не нужна, когда я был единственным пользователем.

Наиболее сложным местом, при создании графической оболочки, оказалось отображение игровой доски. Игровая доска Sudoku представляет собой поле 9x9 клеток, на котором выделены в группы квадраты 3х3. Наилучший способ представления такой доски заключается в отрисовке линий по краям каждой клетки, а затем поднятии квадратов 3х3 более толстой линией.

Игровую доску я реализовал как виджет, потомок GtkTable с таблицей 9х9 ячеек. В каждой ячейке находится другой виджет, наследующий свойства GtkDrawingArea. Виджет игровой доски отвечает за то, что между виджетами клеток нет расстояния и что все клетки имеют одинаковый размер. Cairo используется при отрисовке линий и чтобы сделать все клетки динамически расширяемыми. Граничные линии каждой клетки отрисовываются в зависимости от её местоположения. Прежде чем прийти к такому решению, я исследовал несколько вариантов.

Первой проблемой для меня стал поиск документации, по использованию Cairo в GTK+. Чтобы разрешить её, я предпринял несколько шагов. Во-первых, я отыскал и проштудировал статью Дэвида Мадэли о создании виджетов с использованием Cairo. Во-вторых, я сделал закладку и часто обращался к HTML-документам в папке /usr/share/gtk-doc/html. И самое главное, я распаковал 3 архива с исходниками GTK+ и создал файл с тегами Emacs для всех файлов с исходниками и заголовками. Я нахожу исходники наиболее полезными, а единый стиль форматирования кода, которому они следуют, облегчает навигацию по ним.

Портирование GTK Sudoku

GTK Sudoku собран с использованием GNU Build Tools (еще известными как Autotools). Все, что необходимо сделать, чтобы проверить наличие GTK+ в системе, – это добавить в файл configure.ac строку
AM_PATH_GTK_2_0(2.8.0,, [AC_MSG_ERROR([Cannot find GTK+])])
и еще строку
@GTK_CFLAGS@ and @GTK_LIBS@
в файл Makefile.am.

Использование GNU Build Tools делает перенос GTK Sudoku на различные GNU/Linux дистрибутивы тривиальной задачей. Что касается Mac'ов, я установил версию X11, которая поставлялась с машиной, и использовал DarwinPorts, чтобы установить GTK. После этого GTK Sudoku скомпилировался так, как будто это был GNU/Linux. Создание собственного port-файла не было сложной задачей. Единственное, что пришлось добавить при заполнении полей это:
depends_lib port:gtk2

В отличии от Linux и Mac, портирование GTK Sudoku на Windows представляло собой сложную задачу. Создание окружения разработчика на основе MinGW и MSYS отличалось от того, как это делалось для других графических инструментариев, которые я раньше использовал. Например, используя FLTK любой может загрузить исходники, а затем легко скомпилировать и установить инструментарий. В отличии от этого, GTK+ зависит от большого числа пакетов, которые не входят в стандартные дистрибутивы MinGW и MSYS.

Установить окружение разработчика из предварительно скомпилированных файлов достаточно сложно и может отпугнуть любого, кто собирается использовать исходники. Дополнительно существует ряд технических причин, которые значительно усложняют сборку окружения, допускающего статическую компоновку приложений GTK+. В результате многие разработчики предпочитают использовать коллекцию архивов, любезно предоставленную Тором Лилквистом (Tor Lillqvist). Этот дистрибутив здорово подходит новичкам, за что я особенно благодарен Тору. Были трудности и при использовании этого дистрибутива, но они все преодолимы.

При переносе приложения на Windows портировать приложение GTK+ немного сложнее, чем приложение FLTK или WxWindows. Если следовать рекомендациям из документации по FLTK и WxWidgets, ваша система сборки будет работать без изменений на всех системах, включая MSYS. При использовании MSYS компоновщику обычно указывают опцию -mwindows, которая добавляется к конфигурационным скриптам графического инструментария; в то же время скрипт конфигурирования GTK+ игнорирует эту опцию. Я поборол эту проблему, добавив этот флаг в файл /usr/local/lib/pkgconfig/gdk-2.0.pc.

Самой большой оказалась проблема создания инсталлятора для GTK Sudoku под Windows. Для GTK+ 2.8.18 существует инсталлятор исполняемой среды под Windows. Но вот незадача, последняя версия окружения разработчика поставляется с GTK+ 2.8.20. Тем не менее, можно извернуться и запустить GTK Sudoku, собранный с GTK+ 2.8.20, в исполняемой среде GTK+ 2.8.18, добавив определение функции g_type_register_static_simple, которая была добавлена после выхода 2.8.18. Чем не хак?

Инсталлятор GTK Sudoku получился близок к десятимегабайтному ограничению LuaForge по размеру файла. А все потому, что пришлось включить почти все файлы из инсталлятора GTK+ 2.8.18 в инсталлятор GTK Sudoku. Если установить GTK+ 2.8.18 в общий каталог, некоторые другие приложения GTK+, например, Gaim, могут перестать работать.

Один раз поместив исполняемую среду в инсталлятор, можно смело менять её компоненты. Так, чтобы решить проблему компоновки, Тор Лилквист посоветовал мне обновить библиотеку Glib до версии 2.12.

Заключение

В общем, я был впечатлён возможностями GTK+ и в особенности Cairo. Тем не менее, портирование приложений под Windows хотя и не является не возможным, требует дополнительных усилий. В общем, надо проявить лишь чуточку упорства и все получиться.