<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://wiki2.linuxformat.ru/skins/common/feed.css?97"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF95%3AGTK%2B</id>
		<title>LXF95:GTK+ - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF95%3AGTK%2B"/>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF95:GTK%2B&amp;action=history"/>
		<updated>2026-05-14T03:14:20Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.11.1</generator>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF95:GTK%2B&amp;diff=6044&amp;oldid=prev</id>
		<title>Yaleks: викификация</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF95:GTK%2B&amp;diff=6044&amp;oldid=prev"/>
				<updated>2008-12-15T20:34:07Z</updated>
		
		<summary type="html">&lt;p&gt;викификация&lt;/p&gt;
&lt;a href=&quot;http://wiki2.linuxformat.ru/index.php?title=LXF95:GTK%2B&amp;amp;diff=6044&amp;amp;oldid=6043&quot;&gt;(Различия между версиями)&lt;/a&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF95:GTK%2B&amp;diff=6043&amp;oldid=prev</id>
		<title>Yaleks: Новая: {{Цикл/GTK+}} == Заключительные штрихи == ''ЧАСТЬ 9 Пришла пора ставить точку — но напоследок '''Андрей Боров...</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF95:GTK%2B&amp;diff=6043&amp;oldid=prev"/>
				<updated>2008-12-15T20:32:52Z</updated>
		
		<summary type="html">&lt;p&gt;Новая: {{Цикл/GTK+}} == Заключительные штрихи == ''ЧАСТЬ 9 Пришла пора ставить точку — но напоследок '''Андрей Боров...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая статья&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Цикл/GTK+}}&lt;br /&gt;
== Заключительные штрихи ==&lt;br /&gt;
''ЧАСТЬ 9 Пришла пора ставить точку — но напоследок '''Андрей Боровский''' изыскал возможность рассказать о двух блестящих компонентах GNOME и работе с GTK из C++.''&lt;br /&gt;
&lt;br /&gt;
Сегодня мы завершим беглый обзор основных библиотек&lt;br /&gt;
GNOME, начатый в предыдущей статье, примером использования libgnomeui. Эта библиотека содержит несколько дополнительных визуальных компонентов, призванных, как сказано в документации, заставить интерфейс программы GNOME сверкать по-настоящему. В нашем примере мы рассмотрим два блистательных виджета&lt;br /&gt;
из библиотеки libgnomeui – GnomeDruid и GnomeIconSelection.&lt;br /&gt;
&lt;br /&gt;
Компонент GnomeDruid предназначен для создания мастеров (хотя&lt;br /&gt;
в русском переводе интерфейса GNOME эти компоненты именуются&lt;br /&gt;
«помощниками», я предпочитаю называть их именно так), сопровождающих пользователя через последовательные этапы некоего процесса конфигурации или выбора параметров. Пример использования&lt;br /&gt;
GnomeDruid, который должен быть вам уже хорошо знаком – это мастер создания нового проекта в интегрированной среде Anjuta.&lt;br /&gt;
&lt;br /&gt;
Второй из рассматриваемых компонентов, GnomeIconSelection,&lt;br /&gt;
представляет собой окно, в которое может быть загружен набор пиктограмм. Этот компонент применяется в тех случаях, когда необходимо предоставить пользователю возможность выбрать пиктограмму&lt;br /&gt;
из заранее заданного набора. Оба компонента относятся к категории контейнеров (GnomeDruid является потомком GtkContainer, а&lt;br /&gt;
GnomeIconSelection – потомком GtkVBox).&lt;br /&gt;
&lt;br /&gt;
[[Изображение:Img 95 78 1.png|thumb|Рис. 1. Создание мастера (помощника) в среде Glade.]]&lt;br /&gt;
Создадим в среде Anjuta новый проект приложения GNOME с&lt;br /&gt;
использованием Glade (программа, которую вы найдете на диске,&lt;br /&gt;
называется druiddemo). В форму главного окна приложения помещаем&lt;br /&gt;
компонент «Помощник» (то есть «мастер») со вкладки Gnome палитры компонентов Glade. При этом система спросит нас (Рис. 1), сколько&lt;br /&gt;
страниц должен содержать создаваемый мастер (количество страниц&lt;br /&gt;
можно будет изменить позднее, во время редактирования).&lt;br /&gt;
&lt;br /&gt;
[[Изображение:Img 95 78 2.png|thumb|Рис. 2. Страница мастера в режиме редактирования.]]&lt;br /&gt;
Рассчитывая количество страниц будущего мастера, следует учесть,&lt;br /&gt;
что первая и последняя страницы обычно не содержат специальных&lt;br /&gt;
элементов управления – они предназначены для вывода текста. Текст&lt;br /&gt;
на первой странице обычно поясняет назначение мастера, а текст на&lt;br /&gt;
последней странице поздравляет пользователя с успешным решением&lt;br /&gt;
задачи и, возможно, объясняет, что следует делать дальше. Первая и&lt;br /&gt;
последняя страницы содержат поля для вывода текста и заголовков, а&lt;br /&gt;
также некоторые свойства, позволяющие задать дополнительные элементы оформления этих страниц. Все промежуточные страницы мастера, которые, собственно, и реализуют его функциональность, включают в себя поле для вывода заголовка страницы и контейнер GtkVBox, в&lt;br /&gt;
котором вы можете размещать любые визуальные элементы (Рис. 2).&lt;br /&gt;
&lt;br /&gt;
Переключение между страницами мастера во время редактирования выполняется так же, как и во время выполнения, то есть с помощью кнопок Назад и Далее. Наш демонстрационный мастер содержит&lt;br /&gt;
всего три страницы, то есть в нем будет только одна страница с элементами управления. Поместив компонент-мастер в главное окно приложения, мы можем исследовать, какие объекты были сгенерированы&lt;br /&gt;
для него Glade. Прежде всего, это объект druid1 класса GnomeDruid.&lt;br /&gt;
Первая страница мастера представлена структурой druidpagestart1 типа&lt;br /&gt;
GnomeDruidPageEdge. Свойство Заголовок этого объекта позволяет&lt;br /&gt;
указать заголовок начальной страницы мастера, в свойстве Текст мы&lt;br /&gt;
вводим текст.&lt;br /&gt;
&lt;br /&gt;
Помимо этих двух свойств, класс GnomeDruidPageEdge обладает и другими, позволяющими указать цвет шрифта и фона для&lt;br /&gt;
заголовка и текста, а также отобразить эмблему мастера в правом&lt;br /&gt;
верхнем углу страницы и фоновый узор (watermarks) – в верхней&lt;br /&gt;
части страницы. Страница, на которой мы будем размещать элементы управления, представлена структурой druidpagestandard1 типа&lt;br /&gt;
GnomeDruidPageStandard. На ней расположен контейнер druid-vbox1&lt;br /&gt;
типа GtkVBox. У структуры GnomeDruidPageStandard тот же набор&lt;br /&gt;
свойств, что и у структуры GnomeDruidPageEdge, за исключением свойства Текст (вместо него страница отображает содержимое контейнера).&lt;br /&gt;
Последняя страница мастера, druidpagefinish1, является объектом типа&lt;br /&gt;
GnomeDruidPageEdge, так же как и первая.&lt;br /&gt;
&lt;br /&gt;
Помимо сигналов, унаследованных от своих предков, с объектами&lt;br /&gt;
GnomeDruid связаны два специальных сигнала – help и cancel. Первый&lt;br /&gt;
сигнал генерируется тогда, когда пользователь запрашивает справку; второй сигнал посылается приложению в результате щелчка по&lt;br /&gt;
кнопке «Отмена», которая присутствует на каждой странице мастера.&lt;br /&gt;
Мы назначаем обработчик сигнала cancel объекта druid1 (функция&lt;br /&gt;
on_druid1_cancel()). Поскольку наша программа фактически состоит&lt;br /&gt;
из одного мастера, будет вполне логично вызвать в нем функцию gtk_main_quit(). Объекты GnomeDruidPageEdge и GnomeDruidPageStandard,&lt;br /&gt;
реализующие страницы мастера, обладают одинаковым набором&lt;br /&gt;
дополнительных сигналов: back, next, cancel, finish и prepare.&lt;br /&gt;
&lt;br /&gt;
Первые три сигнала посылаются приложению в ответ на щелчки по&lt;br /&gt;
кнопкам Назад, Далее и Отмена соответственно. Сигнал prepare посылается приложению перед загрузкой соответствующей страницы, а&lt;br /&gt;
сигнал finish – при щелчке по кнопке Применить, которая обычно расположена на последней странице мастера. Обратите внимание на то,&lt;br /&gt;
что сигнал cancel есть как у объекта-мастера, так и у объекта-страницы.&lt;br /&gt;
Зачем нужны два сигнала и как они взаимодействуют между собой?&lt;br /&gt;
Если мы назначили обработчики обоим сигналам, то в ответ на щелчок&lt;br /&gt;
кнопки Отмена на соответствующей странице будут, что вполне логично, вызваны оба обработчика. При этом сначала вызывается обработчик сигнала cancel объекта, реализующего страницу.&lt;br /&gt;
&lt;br /&gt;
В то время как функция обработчика сигнал cancel объекта класса&lt;br /&gt;
GnomeDruid возвращает значение void, функция обработчика cancel&lt;br /&gt;
объекта страницы возвращает значение булевского типа. Если обработчик сигнала cancel объекта-страницы возвращает значение TRUE,&lt;br /&gt;
обработчик сигнала cancel объекта класса GnomeDruid вызван не будет.&lt;br /&gt;
Таким образом, назначая обработчик сигнала cancel объекта класса&lt;br /&gt;
GnomeDruid и обработчик одноименного сигнала cancel для объекта&lt;br /&gt;
страницы, мы можем запретить досрочное завершение работы мастера&lt;br /&gt;
на соответствующей странице.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;void on_druid1_cancel(GnomeDruid * gnomedruid, gpointer user_data)&lt;br /&gt;
{&lt;br /&gt;
gtk_main_quit();&lt;br /&gt;
}&lt;br /&gt;
gboolean on_druidpagestandard1_cancel (GnomeDruidPage *&lt;br /&gt;
gnomedruidpage,&lt;br /&gt;
GtkWidget * widget, gpointer user_data)&lt;br /&gt;
{&lt;br /&gt;
return TRUE;&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
В нашем примере обработчик on_druidpagestandard1_cancel() запрещает завершение мастера на странице druidpagestandard1 (напоминаю&lt;br /&gt;
характерную особенность интерфейса GTK+: когда обработчик сигнала&lt;br /&gt;
должен запретить какие-либо дополнительные действия, он возвращает&lt;br /&gt;
значение TRUE, в противном случае – значение FALSE). Впрочем, рассчитывать на этот метод запрета выхода из мастера особо не следует. Даже&lt;br /&gt;
если обработчик сигнала cancel не позволит завершить работу мастера,&lt;br /&gt;
пользователь все равно сможет сделать это, просто закрыв окно мастера&lt;br /&gt;
с помощью кнопки «X», находящейся в его заголовке.&lt;br /&gt;
&lt;br /&gt;
Сигнал finish посылается приложению тогда, когда пользователь&lt;br /&gt;
щелкает кнопку Применить на странице GnomeDruidPageEdge. Как&lt;br /&gt;
уже отмечалось, этот сигнал есть и у класса GnomeDruidPageStandard,&lt;br /&gt;
однако при обычных условиях (без манипуляций с кнопками) промежуточная страница мастера этот сигнал не получит.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:Img 95 79 1.png|thumb|Рис. 3. Компонент GnomeIconSelection с загруженными пиктограммами.]]&lt;br /&gt;
На странице druidpagestandard1 мы помещаем компонент&lt;br /&gt;
GnomeIconSelection. Компонент GnomeIconSelection может быть очень&lt;br /&gt;
красив, но в режиме редактирования мы увидим только чистое окно&lt;br /&gt;
с полосой прокрутки. Во время выполнения программы мы должны&lt;br /&gt;
указать компоненту источник пиктограмм для отображения и сделать&lt;br /&gt;
отображаемые пиктограммы видимыми. Мы выполняем эти действия в&lt;br /&gt;
обработчике сигнала prepare объекта druidpagestandard1:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;void on_druidpagestandard1_prepare (GnomeDruidPage&lt;br /&gt;
*gnomedruidpage, GtkWidget * widget,&lt;br /&gt;
gpointer user_data)&lt;br /&gt;
{&lt;br /&gt;
GnomeIconSelection * gis = lookup_widget(widget, “iconselection1”);&lt;br /&gt;
gnome_icon_selection_add_defaults (gis);&lt;br /&gt;
gnome_icon_selection_show_icons(gis);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
Функция gnome_icon_selection_add_defaults() добавляет в список&lt;br /&gt;
пиктограмм iconselection1 набор пиктограмм GNOME, заданных по&lt;br /&gt;
умолчанию. Функция gnome_icon_selection_add_directory() позволяет&lt;br /&gt;
добавить набор пиктограмм из произвольно заданной директории. Мы&lt;br /&gt;
можем добавить в список GnomeIconSelection несколько наборов пиктограмм. Чтобы сделать пиктограммы видимыми, вызовем функцию&lt;br /&gt;
gnome_icon_selection_show_icons(). В результате окно компонента&lt;br /&gt;
заполняется симпатичными пиктограммами GNOME (Рис. 3).&lt;br /&gt;
&lt;br /&gt;
Компонент GnomeIconSelection позволяет не только разглядывать пиктограммы, но и выбирать их. В обработчике сигнала next&lt;br /&gt;
объекта druidpagestandard1 мы проверяем, выбрал ли пользователь&lt;br /&gt;
пиктограмму:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;gboolean on_druidpagestandard1_next (GnomeDruidPage &lt;br /&gt;
*gnomedruidpage,&lt;br /&gt;
GtkWidget * widget, gpointer user_data)&lt;br /&gt;
{&lt;br /&gt;
GnomeIconSelection * gis = lookup_widget(widget, “iconselection1”);&lt;br /&gt;
char * icon = gnome_icon_selection_get_icon(gis, TRUE);&lt;br /&gt;
if (icon != NULL) {&lt;br /&gt;
strncpy(selected_icon, icon, 255);&lt;br /&gt;
gnome_icon_selection_clear (gis, TRUE);&lt;br /&gt;
return FALSE;&lt;br /&gt;
}&lt;br /&gt;
return TRUE;&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
Функция gnome_icon_selection_get_icon() возвращает имя файла выбранной пиктограммы или NULL, если ни одна пиктограмма&lt;br /&gt;
не выбрана. Второй параметр функции указывает, должно ли имя&lt;br /&gt;
файла пиктограммы содержать полный путь. Строка, возвращенная&lt;br /&gt;
функцией gnome_icon_selection_get_icon(), не выделяется специально для нас, и мы не должны пытаться ее высвободить. Если пользователь выбрал пиктограмму, мы копируем ее имя в переменную&lt;br /&gt;
selected_icon.&lt;br /&gt;
&lt;br /&gt;
Как и обработчик сигнала cancel, обработчик сигнала next позволяет разрешить или запретить последующие действия с помощью возвращаемого значения. Пока пиктограмма не выбрана, мы не разрешаем пользователю переход на следующую страницу мастера.&lt;br /&gt;
&lt;br /&gt;
Обратите внимание на функцию gnome_icon_selection_clear(). Эта&lt;br /&gt;
функция очищает список пиктограмм. Если мы не будем очищать список пиктограмм каждый раз, когда пользователь покидает страницу с&lt;br /&gt;
компонентом GnomeIconSelection, при каждом возвращении пользователя на эту страницу в компонент будет добавляться новая копия того&lt;br /&gt;
же самого набора пиктограмм. По этой причине мы должны вызвать&lt;br /&gt;
функцию gnome_icon_selection_clear() также и в обработчике сигнала&lt;br /&gt;
back.&lt;br /&gt;
&lt;br /&gt;
Когда пользователь переходит на последнюю страницу мастера, у&lt;br /&gt;
него появляется возможность щелкнуть кнопку Применить. В обработчике соответствующего сигнала finish мы назначаем выбранную пользователем пиктограмму главному окну приложения:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;void on_druidpagefinish1_finish(GnomeDruidPage * gnomedruidpage,&lt;br /&gt;
GtkWidget * widget, gpointer user_data)&lt;br /&gt;
{&lt;br /&gt;
GtkWindow * wnd = lookup_widget(widget, “window1”);&lt;br /&gt;
gtk_window_set_icon_from_file(wnd, selected_icon, NULL);&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GTK+ плюс C++ ===&lt;br /&gt;
Как отмечалось в самой первой статье этой серии, построение GTK+&lt;br /&gt;
на основе C является определенным преимуществом, так как упрощает создание интерфейсов GTK+ для других языков программирования.&lt;br /&gt;
Однако вдумчивый читатель этих статей наверняка ловил себя на мысли, что объектно-ориентированная структура GTK+ и GNOME API очень&lt;br /&gt;
хорошо подходит для реализации на C++. Интерфейс С++ для GTK+ и&lt;br /&gt;
GNOME реализован в наборах библиотек gtkmm и gnomemm. Прежде&lt;br /&gt;
чем приступать к разбору примеров gtkmm, убедитесь, что соответствующие пакеты установлены в вашей системе. Интерфейсы C++ для&lt;br /&gt;
GNOME (gnomemm) не устанавливаются вместе с gtkmm по умолчанию.&lt;br /&gt;
Их следует инсталлировать отдельно.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим простенькую программу, написанную с использованием gtkmm (файл hellogtkmm.cpp на диске):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;gtkmm.h&amp;gt;&lt;br /&gt;
class MainWindow : public Gtk::Window&lt;br /&gt;
{&lt;br /&gt;
Gtk::Button m_button;&lt;br /&gt;
public:&lt;br /&gt;
MainWindow(): m_button(&amp;quot;Здравствуй, gtkmm!&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
set_border_width(10);&lt;br /&gt;
m_button.signal_clicked().connect(sigc::mem_fun(*this,&lt;br /&gt;
&amp;amp;MainWindow::on_button_clicked));&lt;br /&gt;
add(m_button);&lt;br /&gt;
m_button.show();&lt;br /&gt;
}&lt;br /&gt;
virtual ~MainWindow()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
protected:&lt;br /&gt;
virtual void on_button_clicked()&lt;br /&gt;
{&lt;br /&gt;
std::cout &amp;lt;&amp;lt; &amp;quot;Button is pressed&amp;quot; &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
}&lt;br /&gt;
};&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
Gtk::Main prog(argc, argv);&lt;br /&gt;
MainWindow window;&lt;br /&gt;
window.set_title(&amp;quot;Превая программа gtkmm&amp;quot;);&lt;br /&gt;
prog.run(window);&lt;br /&gt;
return 0;&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
[[Изображение:Img 95 80 1.png|thumb|Рис. 4. Программа hellogtkmm.]]&lt;br /&gt;
Эта программа делает то же, что и первая программа из первой статьи этой серии – создает окно с кнопкой (Рис. 4). Конечно, эта программа выглядит совсем не так эффектно, как предыдущая, написанная на&lt;br /&gt;
«чистом» GTK+, но что уж тут поделать – изучение интерфейсов программирования развивается диалектично. Что дает нам использование&lt;br /&gt;
интерфейса C++ для GTK+, написанного на C? Прежде всего – возможность более удобной группировки кода.&lt;br /&gt;
&lt;br /&gt;
Главное окно нашей программы реализовано в классе MainWindow,&lt;br /&gt;
который является потомком класса Gtk::Window (пространство имен&lt;br /&gt;
Gtk содержит классы, связанные с визуальными элементами GTK+).&lt;br /&gt;
Кнопка в нашей программе реализована с помощью объекта m_button&lt;br /&gt;
класса Gtk::Button. В конструкторе класса MainWindow мы прежде&lt;br /&gt;
всего создаем объект m_button. В параметре конструктора Gtk::Button&lt;br /&gt;
передается текст кнопки. Метод set_border_width(), унаследованный&lt;br /&gt;
классом MainWindow от Gtk::Window, делает то же, что сделала бы&lt;br /&gt;
функция gtk_container_set_border_width() для объекта GtkWindow.&lt;br /&gt;
Здесь мы сталкиваемся с общим правилом «перевода» C-интерфейсов GTK+ в C++ интерфейсы gtkmm. Допустим, в интерфейсе GTK+&lt;br /&gt;
определена функция gtk_somewidget_do_something(), оперирующая&lt;br /&gt;
данными структуры GtkSomeWidget. В gtkmm этой функции соответствует метод do_something() класса Gtk::SomeWidget. По правилам интерфейса GTK+, первым аргументом функции gtk_somewidget_do_something() должен быть указатель на экземпляр структуры&lt;br /&gt;
GtkSomeWidget (или ее потомка), для которого вызывается функция.&lt;br /&gt;
Метод Gtk::SomeWidget::do_something(), если он не статический, тоже&lt;br /&gt;
получает в качестве первого аргумента указатель на объект класса&lt;br /&gt;
Gtk::SomeWidget (или его класса-потомка), с той разницей, что в C++&lt;br /&gt;
передача указателя на объект, для которого вызван метод, выполняется неявно, через переменную this, так что в заголовке метода do_something() данный указатель можно опустить.&lt;br /&gt;
&lt;br /&gt;
Если структура GtkOtherWidget является потомком GtkSomeWidget&lt;br /&gt;
в иерархии GTK+, (как например, структура GtkWindow происходит от&lt;br /&gt;
GtkContainer), то соответствующий ей класс Gtk::OtherWidget является&lt;br /&gt;
потомком Gtk::SomeWidget и наследует все доступные методы последнего. Таким образом, метод add() (с помощью которого мы добавляем&lt;br /&gt;
кнопку в окно) класса Gtk::Window унаследован этим классом от класса&lt;br /&gt;
Gtk::Container, в котором он соответствует функции gtk_container_add(),&lt;br /&gt;
а метод show() объекта Gtk::Button унаследован от класса Gtk::Widget и&lt;br /&gt;
соответствует функции gtk_widget_show().&lt;br /&gt;
&lt;br /&gt;
Пространство имен Gtk становится доступно нам благодаря включению в текст программы файла gtkmm.h. Этот заголовочный файл&lt;br /&gt;
включает в себя все заголовочные файлы gtkmm. С одной стороны,&lt;br /&gt;
это хорошо, так как мы можем не опасаться, что забыли включить в&lt;br /&gt;
текст программы объявление какого-либо нужного класса. С другой&lt;br /&gt;
стороны, при использовании gtkmm.h препроцессору придется обработать около мегабайта заголовочных файлов, большая часть из которых&lt;br /&gt;
конкретной программе не нужна. Поэтому в более сложных программах рекомендуется вместо одного универсального gtkmm.h включать в&lt;br /&gt;
исходные тексты специализированные файлы (gtkmm/main.h, gtkmm/button.h и т.д.).&lt;br /&gt;
&lt;br /&gt;
Пропустим, пока что, остальную часть конструктора и перейдем к&lt;br /&gt;
функции main(). Здесь настоящее объектно-ориентированное программирование проявляет себя во всей красе. Любая программа gtkmm&lt;br /&gt;
должна начинаться с инициализации объекта класса Gtk::Main (этот&lt;br /&gt;
объект должен быть объявлен внутри функции main(), а не глобально). У класса Gtk::Main несколько конструкторов, мы выбираем самый&lt;br /&gt;
простой из них, тот, которому передаются переменные argc и argv. Как&lt;br /&gt;
вы, конечно, уже догадались, в программе может быть только один&lt;br /&gt;
объект класса Gtk::Main. Система gtkmm сама следит за тем, чтобы в&lt;br /&gt;
программе не появилось второго объекта Gtk::Main, так что если вы&lt;br /&gt;
попытаетесь создать еще один объект этого класса, вы все равно получите ссылку на тот объект, который вы создали в начале [данная конструкция часто называется «синглетон», – прим. ред.].&lt;br /&gt;
&lt;br /&gt;
Далее мы создаем объект класса MainWindow. Все, что касается&lt;br /&gt;
внутренностей главного окна приложения (как в смысле визуальных&lt;br /&gt;
элементов, так и в смысле данных), инкапсулировано в этом объекте, так что в главной функции нам достаточно передать ссылку (не&lt;br /&gt;
указатель!) на объект класса MainWindow методу run() объекта Gtk::Main. В результате главное окно программы будет выведено на экран и&lt;br /&gt;
начнет обработку адресованных ему сообщений графической системы.&lt;br /&gt;
Закрытие главного окна приведет к выходу из метода run() и завершению программы.&lt;br /&gt;
&lt;br /&gt;
Обратите внимание на то, что в отличие от GTK+, в gtkmm цикл&lt;br /&gt;
обработки сообщений завершается вместе с закрытием главного окна.&lt;br /&gt;
В приведенном выше примере метод run() был вызван как метод объекта prog для того, чтобы сделать код более понятным. На самом деле&lt;br /&gt;
этот метод статический. Благодаря тому, что система gtkmm всегда&lt;br /&gt;
«знает», как найти созданный в программе объект Gtk::Main, мы можем&lt;br /&gt;
обращаться к нему, используя статические методы. Например, вместо&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;prog.run(window);&amp;lt;/source&amp;gt;&lt;br /&gt;
можно написать&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;Gtk::Main::run(window);&amp;lt;/source&amp;gt;&lt;br /&gt;
Вызов window.set_title(), как вы уже знаете, эквивалентен gtk_window_set_title() в GTK+.&lt;br /&gt;
&lt;br /&gt;
Вот мы и научились «переводить» программные конструкции с&lt;br /&gt;
языка GTK+ на язык gtkmm. Это нетрудно, поскольку почти каждой&lt;br /&gt;
функции GTK+ соответствует метод какого-либо класса gtkmm. Но&lt;br /&gt;
что делать, если нам все же понадобится вызвать функцию GTK+ для&lt;br /&gt;
объекта gtkmm? У класса Gtk::Widget и всех его потомков есть метод&lt;br /&gt;
gobj(), который возвращает указатель на соответствующую структуру&lt;br /&gt;
GTK+. Например, метод Gtk::Button::gobj() возвращает значение типа&lt;br /&gt;
GtkButton*, которое можно передавать функциям GTK+.&lt;br /&gt;
&lt;br /&gt;
Перегруженная функция wrap() из пространства имен Glib выполняет обратную операцию, то есть создает на основе структуры GTK+&lt;br /&gt;
объект класса gtkmm:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;GtkButton * b = GTK_BUTTON(gtk_button_new_with_label (“fine button”));&lt;br /&gt;
Gtk::Button * button = Glib::wrap(b);&amp;lt;/source&amp;gt;&lt;br /&gt;
Вернемся теперь к конструктору MainWindow. Как вы, наверное,&lt;br /&gt;
заметили, мы пропустили код, связанный с назначением обработчика&lt;br /&gt;
сигнала clicked кнопки m_button. Прежде чем мы перейдем к описанию&lt;br /&gt;
механизмов обработки сигналов gtkmm, позвольте небольшое лирическое отступление. Простые идеи обработки событий, заложенные в&lt;br /&gt;
Delphi, Borland C++Builder и C#, почему-то не в чести у разработчиков&lt;br /&gt;
открытых наборов графических компонентов. Эти парни не любят простых путей! Вспомните систему сигналов и слотов в Qt, требующую&lt;br /&gt;
применения макросов и специального препроцессора...&lt;br /&gt;
&lt;br /&gt;
Разработчики gtkmm шагнули еще дальше и задействовали для&lt;br /&gt;
обработки событий «тяжелую артиллерию» C++ – функторы, адаптеры&lt;br /&gt;
и шаблоны. Все управление обработкой сигналов в gtkmm выполняет&lt;br /&gt;
библиотека libsigc. Если вы хотите досконально разобраться в том, как&lt;br /&gt;
создаются, живут и умирают обработчики сигналов, изучайте документацию к этой библиотеке (которая, кстати, не слишком хороша).&lt;br /&gt;
Нижеизложенное является лишь мягким введением в вопрос.&lt;br /&gt;
&lt;br /&gt;
У каждого класса gtkmm, реализующего визуальный элемент GTK+,&lt;br /&gt;
есть набор методов, соответствующих сигналам, которые может генерировать данный визуальный элемент. Каждый из этих методов возвращает прокси-объект, созданный на основе шаблона sigc::signal, его&lt;br /&gt;
можно использовать для назначения обработчика сигнала.&lt;br /&gt;
&lt;br /&gt;
Метод signal_clicked() объекта m_button возвращает прокси-объект&lt;br /&gt;
для назначения обработчика сигнала clicked.&lt;br /&gt;
&lt;br /&gt;
Метод connect() прокси-объекта осуществляет фактическое связывание обработчика и сигнала. Аргументом метода connect() может&lt;br /&gt;
быть объект-слот или объект-функция (называемая также «функтор»),&lt;br /&gt;
который мы создаем с помощью адаптера sigc::mem_fun(). Этот адаптер создает объект-функцию из метода класса (первым аргументом&lt;br /&gt;
адаптера является указатель this, вторым – адрес метода). Если бы&lt;br /&gt;
обработчик сигнала был обычной функцией, нам следовало бы воспользоваться адаптером sigc::ptr_fun(). У метода connect() есть еще&lt;br /&gt;
один параметр булевского типа, который позволяет указать, должен&lt;br /&gt;
ли обработчик вызываться после стандартного обработчика (по умолчанию этому параметру присвоено значение TRUE).&lt;br /&gt;
&lt;br /&gt;
В результате всех этих манипуляций метод on_button_clicked() становится обработчиком сигнала clicked объекта m_button. Рассмотренный&lt;br /&gt;
механизм позволяет назначать сигналу несколько обработчиков.&lt;br /&gt;
&lt;br /&gt;
В общем случае метод connect возвращает объект, описываемый&lt;br /&gt;
страшной конструкцией sigc::signal&amp;lt;void,int&amp;gt;::iterator. Этот объект легко&lt;br /&gt;
преобразовать к типу sigc::connection. С помощью метода disconnect()&lt;br /&gt;
объекта класса sigc::connection мы можем удалить назначенный сигналу обработчик:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;sigc::connection connection;&lt;br /&gt;
...&lt;br /&gt;
connection = m_button.signal_clicked().connect(sigc::mem_fun(*this,&lt;br /&gt;
&amp;amp;MainWindow::on_button_clicked));&lt;br /&gt;
...&lt;br /&gt;
connection.disconnect();&amp;lt;/source&amp;gt;&lt;br /&gt;
Если все это кажется вам слишком сложным, можете пойти другим&lt;br /&gt;
путем. У класса Gtk::Button есть метод on_clicked(), объявленный в разделе protected. Вы можете перекрыть этот метод в потомке Gtk::Button&lt;br /&gt;
(только не забудьте вызвать метод базового класса, иначе результаты&lt;br /&gt;
могут оказаться несколько неожиданными). При таком подходе вам,&lt;br /&gt;
конечно, придется создавать собственный класс для каждой кнопки&lt;br /&gt;
вашего приложения [думается, что отчасти поэтому разработчики GTK+&lt;br /&gt;
и Qt и решили не идти «путем Delphi», – прим. ред.].&lt;br /&gt;
&lt;br /&gt;
Ну вот, пожалуй, и все, что можно было сказать о gtkmm в рамках&lt;br /&gt;
одной статьи. Если вас интересует, как скомпилировать программу-пример командой в одну строку, то вот она, команда, использующая&lt;br /&gt;
утилиту pkg-config:&lt;br /&gt;
 g++ hellogtkmm.cpp -o hellogtkmm 'pkg-config gtkmm-2.4 --cflags --libs'&lt;br /&gt;
&lt;br /&gt;
На этом я завершаю увлекательное путешествие в мир GTK+ и гномов и благодарю всех, кто не потерялся в пути. Встретимся вновь, изучая другие графические инструментарии.&lt;/div&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	</feed>