<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://wiki2.linuxformat.ru/skins/common/feed.css?97"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>LXF84:Qt/KDE - История изменений</title>
		<link>http://wiki2.linuxformat.ru/index.php?title=LXF84:Qt/KDE&amp;action=history</link>
		<description>История изменений этой страницы в вики</description>
		<language>ru</language>
		<generator>MediaWiki 1.11.1</generator>
		<lastBuildDate>Wed, 13 May 2026 23:45:02 GMT</lastBuildDate>
		<item>
			<title>Yaleks: викификация</title>
			<link>http://wiki2.linuxformat.ru/index.php?title=LXF84:Qt/KDE&amp;diff=5990&amp;oldid=prev</link>
			<description>&lt;p&gt;викификация&lt;/p&gt;
&lt;a href=&quot;http://wiki2.linuxformat.ru/index.php?title=LXF84:Qt/KDE&amp;amp;diff=5990&amp;amp;oldid=5989&quot;&gt;(Различия между версиями)&lt;/a&gt;</description>
			<pubDate>Sun, 14 Dec 2008 18:09:24 GMT</pubDate>			<dc:creator>Yaleks</dc:creator>			<comments>http://wiki2.linuxformat.ru/index.php/%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:LXF84:Qt/KDE</comments>		</item>
		<item>
			<title>Yaleks в 18:07, 14 декабря 2008</title>
			<link>http://wiki2.linuxformat.ru/index.php?title=LXF84:Qt/KDE&amp;diff=5989&amp;oldid=prev</link>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;http://wiki2.linuxformat.ru/index.php?title=LXF84:Qt/KDE&amp;amp;diff=5989&amp;amp;oldid=5986&quot;&gt;(Различия между версиями)&lt;/a&gt;</description>
			<pubDate>Sun, 14 Dec 2008 18:07:24 GMT</pubDate>			<dc:creator>Yaleks</dc:creator>			<comments>http://wiki2.linuxformat.ru/index.php/%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:LXF84:Qt/KDE</comments>		</item>
		<item>
			<title>Yaleks: Новая: {{Цикл/Qt/KDE}} == Модули KDE == ''ЧАСТЬ 7: Модули, расширения, расширения расширений.... всKIPIте от напряжения и н...</title>
			<link>http://wiki2.linuxformat.ru/index.php?title=LXF84:Qt/KDE&amp;diff=5986&amp;oldid=prev</link>
			<description>&lt;p&gt;Новая: {{Цикл/Qt/KDE}} == Модули KDE == ''ЧАСТЬ 7: Модули, расширения, расширения расширений.... всKIPIте от напряжения и н...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая статья&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Цикл/Qt/KDE}}&lt;br /&gt;
== Модули KDE ==&lt;br /&gt;
''ЧАСТЬ 7: Модули, расширения, расширения расширений.... всKIPIте от напряжения и нетерпения под присмотром '''Андрея Боровского'''!''&lt;br /&gt;
&lt;br /&gt;
=== Модули KDE ===&lt;br /&gt;
Модули KDE (KDE plugins) представляют собой логическое разви-&lt;br /&gt;
тие идеи объектно-ориентированной оболочки. Читатели этой статьи&lt;br /&gt;
наверняка знакомы с базовыми концепциями модулей как средств рас-&lt;br /&gt;
ширения уже существующих приложений. Механизм модулей позволя-&lt;br /&gt;
ет нам не умножать сущностей (приложений) без необходимости вся-&lt;br /&gt;
кий раз, когда нам требуется новая функциональность. По самой своей&lt;br /&gt;
природе модули тесно связаны с теми приложениями, чьи возможнос-&lt;br /&gt;
ти они расширяют. Нельзя написать «просто модуль». Мы рассмотрим&lt;br /&gt;
программирование модулей для наиболее популярных приложений&lt;br /&gt;
KDE и начнем с написания модуля для компонента KParts.&lt;br /&gt;
&lt;br /&gt;
=== K-Части ===&lt;br /&gt;
Модули KParts широко применяются, например, в браузере Konqueror.&lt;br /&gt;
Сами компоненты KParts представляют собой еще один способ рас-&lt;br /&gt;
ширения возможностей приложения. Примером их использования&lt;br /&gt;
являются встроенные в Konqueror утилиты просмотра файлов различ-&lt;br /&gt;
ных типов. Каждый раз, когда Konqueror открывает какой-либо файл&lt;br /&gt;
для просмотра, он загружает соответствующий компонент, который&lt;br /&gt;
встраивается в интерфейс браузера и отображает содержимое файла.&lt;br /&gt;
Благодаря динамическим компонентам KParts, Konqueror выполняет&lt;br /&gt;
функцию универсального просмотрщика файлов, сохраняя при этом&lt;br /&gt;
простой дизайн и небольшие размеры основного приложения. Следует&lt;br /&gt;
отметить, что универсализм Konqueror иногда подвергается критике,&lt;br /&gt;
поскольку в Unix традиционно преобладает другой подход – использо-&lt;br /&gt;
вание большого числа независимых приложений, каждое из которых&lt;br /&gt;
делает что-то одно. Мы оставим в стороне вопрос о том, нужно ли&lt;br /&gt;
писать модули, и ответим на вопрос, как это можно сделать. Модули&lt;br /&gt;
KParts расширяют возможности компонентов KParts, то есть, с точки&lt;br /&gt;
зрения основной программы Konqueror, модули являются расширени-&lt;br /&gt;
ями расширений. Поддержка модулей KParts возможна, естественно,&lt;br /&gt;
не только в Konqueror, но и в любом приложении, поддерживающем&lt;br /&gt;
соответствующие компоненты KParts.&lt;br /&gt;
&lt;br /&gt;
Возможно, на этом этапе у читателя возникает вопрос – а зачем&lt;br /&gt;
вообще нужны модули Konqueror? Необходимость в механизме моду-&lt;br /&gt;
лей была бы очевидна, если бы Konqueror был закрытым приложени-&lt;br /&gt;
ем, однако, при наличии исходных текстов, мы можем вносить изме-&lt;br /&gt;
нения непосредственно в код компонентов KParts. Это верно, и тем не&lt;br /&gt;
менее модули оказываются полезны и в случае открытого приложения.&lt;br /&gt;
Главное преимущество использования модулей заключается в лучшей&lt;br /&gt;
структурной организации кода. Нам легче писать и отлаживать модули,&lt;br /&gt;
связанные с приложением с помощью строго определенного интер-&lt;br /&gt;
фейса, нежели вносить изменения в исходные тексты приложения,&lt;br /&gt;
написанного другими программистами. К этому следует добавить и&lt;br /&gt;
чисто организационный момент – для того, чтобы изменения, сделан-&lt;br /&gt;
ные вами в приложении, попали в его основную версию, они должны&lt;br /&gt;
быть одобрены другими разработчиками, тогда как в случае с моду-&lt;br /&gt;
лями у вас есть возможность самостоятельно решить, какие функции&lt;br /&gt;
являются полезными, а какие – нет.&lt;br /&gt;
&lt;br /&gt;
Что же представляет собой модуль KParts с точки зрения взаимо-&lt;br /&gt;
действия с приложением? Модуль – это динамическая библиотека&lt;br /&gt;
(файл *.so), которая загружается приложением, использующим компо-&lt;br /&gt;
нент KParts. Модуль может добавлять собственные элементы управле-&lt;br /&gt;
ния в меню и на панель инструментов приложения. В некоторых случаях&lt;br /&gt;
модули также изменяют содержимое главного окна приложения (кото-&lt;br /&gt;
рое в этот момент управляется соответствующим компонентом KParts).&lt;br /&gt;
&lt;br /&gt;
В качестве примера мы напишем модуль для компонента KHTMLPart.&lt;br /&gt;
Как нетрудно догадаться, этот компонент используется для просмотра&lt;br /&gt;
страниц HTML. Фактически KHTMLPart представляет собой полно-&lt;br /&gt;
ценный встраиваемый HTML-браузер с поддержкой JavaScript. Класс&lt;br /&gt;
KHTMLPart является потомком класса KParts::ReadOnlyPart, то есть&lt;br /&gt;
он предназначен для просмотра, а не для модификации открывае-&lt;br /&gt;
мого файла. Наш модуль будет сохранять открытую в компоненте&lt;br /&gt;
KHTMLPart HTML-страницу в простом текстовом формате.&lt;br /&gt;
&lt;br /&gt;
Модуль для KHTMLPart удобен в качестве примера потому, что в&lt;br /&gt;
KDevelop есть шаблон проекта такого модуля. В окне Создать новый&lt;br /&gt;
проект (Рис. 1) мы выбираем пункт KHTMLPart Plugin. Назовем наш&lt;br /&gt;
проект «textsaver» (полные исходные тексты модуля вы найдете на&lt;br /&gt;
диске, в файле textsaver.tar.gz). Наш модуль, как таковой, состоит&lt;br /&gt;
только из двух классов – Plugintextsaver (основной класс модуля) и&lt;br /&gt;
textsaverFactory (вспомогательный класс). Оба класса реализованы в&lt;br /&gt;
файлах plugin_textsaver.h и plugin_textsaver.cpp. Прежде чем вносить&lt;br /&gt;
изменения в классы, добавим в файл plugin_textsaver.cpp дополни-&lt;br /&gt;
тельные заголовочные файлы:&lt;br /&gt;
include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;kfiledialog.h&amp;gt;&lt;br /&gt;
#include &amp;lt;qcstring.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Рассмотрим сначала класс textsaverFactory, являющийся потом-&lt;br /&gt;
ком класса KParts::Factory и управляющий созданием объекта класса&lt;br /&gt;
Plugintextsaver (т.е., этот класс реализует фабрику объектов). Такой объект&lt;br /&gt;
создается методом textsaverFactory::createObject(), который сгенерирован&lt;br /&gt;
автоматически. Нам вообще ничего не нужно было бы менять в классе&lt;br /&gt;
textsaverFactory, если бы не чистый виртуальный метод createPartObject().&lt;br /&gt;
Сам по себе он нам не нужен, но для того, чтобы наш модуль мог скомпи-&lt;br /&gt;
лироваться, мы должны создать его реализацию. Странно, что KDevelop,&lt;br /&gt;
по крайней мере в версии 3.4.2, не делает этого автоматически:&lt;br /&gt;
KParts::Part* createPartObject(&lt;br /&gt;
QWidget*, const char*, QObject*,&lt;br /&gt;
const char*, const char*, const QStringList&amp;amp;)&lt;br /&gt;
{return 0;}&lt;br /&gt;
Помимо прочего, разделяемая библиотека, содержащая наш&lt;br /&gt;
модуль, должна экспортировать функцию, создающую объект класса&lt;br /&gt;
textsaverFactory. Эта функция, сгенерированная автоматически, экс-&lt;br /&gt;
портируется в формате C:&lt;br /&gt;
extern “C”&lt;br /&gt;
{&lt;br /&gt;
void* init_libtextsaverplugin()&lt;br /&gt;
{&lt;br /&gt;
KGlobal::locale()-&amp;gt;insertCatalogue(“textsaver”);&lt;br /&gt;
return new textsaverFactory;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
Приложение, вызывающее функцию init_libtextsaverplugin(), знает,&lt;br /&gt;
что делать с возвращенным указателем.&lt;br /&gt;
Перейдем к классу Plugintextsaver. Приложение, а точнее, ком-&lt;br /&gt;
понент KHTMLPart, взаимодействует с нашим модулем при помощи&lt;br /&gt;
вызова трех методов этого класса – конструктора, деструктора и мето-&lt;br /&gt;
да slotAction(). Метод slotAction() представляет собой слот, который&lt;br /&gt;
вызывается всякий раз, когда пользователь выбирает пункт меню или&lt;br /&gt;
нажимает кнопку, связанную с модулем. Этот метод содержит код,&lt;br /&gt;
который, собственно, и отвечает за выполнение команды. В конструк-&lt;br /&gt;
торе класса Plugintextsaver создается объект-действие:&lt;br /&gt;
Plugintextsaver::Plugintextsaver( QObject* parent, const char* name )&lt;br /&gt;
: Plugin( parent, name )&lt;br /&gt;
{&lt;br /&gt;
(void) new KAction( i18n(“Save as &amp;amp;Text”), “textsaver”, 0,&lt;br /&gt;
this, SLOT(slotAction()),&lt;br /&gt;
actionCollection(), “plugin_action” );&lt;br /&gt;
}&lt;br /&gt;
Этот объект будет добавлен в коллекцию действий приложения,&lt;br /&gt;
вызвавшего компонент KHTMLPart, загрузивший наш модуль. Тем, кто&lt;br /&gt;
не совсем понимает, о очем идет речь, рекомендуем прочитать поза-&lt;br /&gt;
прошлую статью этого цикла (LXF82), в которой мы познакомились с&lt;br /&gt;
объектами-действиями. Мы указываем объекту-действию имя соответ-&lt;br /&gt;
ствующего элемента управления и слот, который должен обрабатывать&lt;br /&gt;
команду. Очевидно, что в общем случае мы можем зарегистрировать&lt;br /&gt;
несколько действий для нашего модуля. Нам осталось написать только&lt;br /&gt;
сам метод slotAction():&lt;br /&gt;
void Plugintextsaver::slotAction()&lt;br /&gt;
{&lt;br /&gt;
if ( !parent()-&amp;gt;inherits(“KHTMLPart”) )&lt;br /&gt;
{&lt;br /&gt;
QString title( i18n(“HTML Only”));&lt;br /&gt;
QString text(i18n(“Only HTML documents can be saved with this&lt;br /&gt;
plugin.”));&lt;br /&gt;
KMessageBox::sorry( 0, text, title );&lt;br /&gt;
return;&lt;br /&gt;
}&lt;br /&gt;
KHTMLPart *part = dynamic_cast&amp;lt;KHTMLPart *&amp;gt;(parent());&lt;br /&gt;
QString FN = KFileDialog::getSaveFileName(“”, “”, 0, “Save Text File&lt;br /&gt;
As”);&lt;br /&gt;
if (FN == “”) return;&lt;br /&gt;
QString Cmd = “html2text &amp;gt; “ + FN;&lt;br /&gt;
QCString Text = part-&amp;gt;documentSource().local8Bit();&lt;br /&gt;
FILE * F = popen(Cmd.ascii(), “w”);&lt;br /&gt;
fwrite((char*) Text.data(), 1, Text.length(), F);&lt;br /&gt;
pclose(F);&lt;br /&gt;
}&lt;br /&gt;
У модуля должна быть какая-то возможность взаимодействовать&lt;br /&gt;
с другими элементами приложения-хозяина (этот термин не следует&lt;br /&gt;
понимать в том смысле, что наш модуль паразитирует на браузере&lt;br /&gt;
Konqueror). Такая возможность у модуля есть, благодаря тому, что&lt;br /&gt;
конструктору объекта модуля был передан указатель на вызвавший его&lt;br /&gt;
объект класса KTHMLPart. Доступ к этому указателю можно получить&lt;br /&gt;
с помощью метода parent(). Первый блок кода в методе slotAction()&lt;br /&gt;
проверяет, действительно ли объект parent() принадлежит классу&lt;br /&gt;
KHTMLPart. На практике это излишне, поскольку модуль никогда не&lt;br /&gt;
будет вызван для какого-либо иного компонента. Далее мы получаем&lt;br /&gt;
указатель на родительский объект KHTMLPart, запрашиваем у пользо-&lt;br /&gt;
вателя имя файла для сохранения текста (надеюсь, вы еще не забыли,&lt;br /&gt;
что должен делать наш модуль) и, с помощью метода documentSource()&lt;br /&gt;
получаем HTML-текст страницы, открытой компонентом KHTMLPart.&lt;br /&gt;
Метод documentSource() возвращает данные в строке QString в двух-&lt;br /&gt;
байтовой кодировке. Мы преобразуем полученную строку в локальную&lt;br /&gt;
однобайтовую кодировку и сохраняем результат в переменной Text&lt;br /&gt;
типа QCString. Далее, с помощью функции popen(3), мы запускаем&lt;br /&gt;
внешнюю утилиту html2text, преобразующую данные HTML в простой&lt;br /&gt;
текст. Этой утилите мы передаем содержимое переменной Text и имя&lt;br /&gt;
файла для сохранения результата. Применяемый нами прием – исполь-&lt;br /&gt;
зование в программе внешней утилиты для решения нашей задачи,&lt;br /&gt;
очень широко распространен в Unix-системах.&lt;br /&gt;
Хотя мы и определили все методы классов нашего модуля, рабо-&lt;br /&gt;
та над ним еще не закончена. Модуль создает новый объект-действие&lt;br /&gt;
для вызвавшего его приложения, но приложение пока не знает, как оно&lt;br /&gt;
должно (и должно ли) отображать соответствующий этому действию&lt;br /&gt;
элемент интерфейса. Наш модуль может дополнить пользовательский&lt;br /&gt;
интерфейс хозяйского приложения с помощью механизма XMLGUI, опи-&lt;br /&gt;
санного в прошлой статье (LXF83). Откройте файл plugin_textsaver.rc:&lt;br /&gt;
&amp;lt;!DOCTYPE kpartgui&amp;gt;&lt;br /&gt;
&amp;lt;kpartplugin name=”textsaver” library=”libtextsaverplugin” version=”1”&amp;gt;&lt;br /&gt;
&amp;lt;MenuBar&amp;gt;&lt;br /&gt;
&amp;lt;Menu name=”tools”&amp;gt;&amp;lt;Text&amp;gt;&amp;amp;amp;Tools&amp;lt;/Text&amp;gt;&lt;br /&gt;
&amp;lt;Action name=”plugin_action”/&amp;gt;&lt;br /&gt;
&amp;lt;/Menu&amp;gt;&lt;br /&gt;
&amp;lt;/MenuBar&amp;gt;&lt;br /&gt;
&amp;lt;ToolBar name=”extraToolBar”&amp;gt;&lt;br /&gt;
&amp;lt;Action name=”plugin_action”/&amp;gt;&lt;br /&gt;
&amp;lt;/ToolBar&amp;gt;&lt;br /&gt;
&amp;lt;/kpartplugin&amp;gt;&lt;br /&gt;
Те, кто читал предыдущую статью, не найдут в этом тексте ничего&lt;br /&gt;
неожиданного. Мы регистрируем два элемента управления – для меню&lt;br /&gt;
и панели быстрого доступа. Команда вызова нашего модуля (Save as&lt;br /&gt;
Text) будет расположена в меню Tools (Сервис), хотя, возможно, сле-&lt;br /&gt;
довало расположить ее в меню Файл. Кнопка команды по умолчанию&lt;br /&gt;
будет расположена на дополнительной панели инструментов, которая&lt;br /&gt;
(опять-таки, по умолчанию) не видна.&lt;br /&gt;
Нам осталось скомпилировать и установить наш модуль. Обычно&lt;br /&gt;
модули устанавливаются в общую системную директорию, например, в&lt;br /&gt;
$KDEDIR/lib/kde3/, так что для установки понадобятся права root. При&lt;br /&gt;
отладке модуля следует учитывать, что текущая версия модуля кэши-&lt;br /&gt;
руется оболочкой Konqueror (и даже ldconfig не помогает), так что для&lt;br /&gt;
того, чтобы увидеть изменения, внесенные после повторной установки&lt;br /&gt;
расширения, вам, возможно, придется перезапускать оболочку.&lt;br /&gt;
Скомпилируйте и установите модуль, после чего запустите новый&lt;br /&gt;
экземпляр Web-браузера (но не файл-менеджера) Konqueror или&lt;br /&gt;
откройте HTML-страницу в файл-менеджере. В меню Сервис вы уви-&lt;br /&gt;
дите команду, вызывающую наш модуль (Рис. 2). Выше уже было ска-&lt;br /&gt;
зано, что система следит за тем, чтобы наш модуль не был вызван для&lt;br /&gt;
неподходящего компонента. Это выражается в том, что соответствую-&lt;br /&gt;
щая команда меню видна тогда, когда мы открываем HTML-страницу, и&lt;br /&gt;
не видна в остальных случаях.&lt;br /&gt;
Если при просмотре сохраненной нашим модулем страницы в каком-&lt;br /&gt;
нибудь текстовом редакторе вы увидите нечто странное, то не спешите&lt;br /&gt;
ругаться. Используемая нами утилита html2text, во-первых, пытается&lt;br /&gt;
сохранить расположение текста, соответствующее его расположению на&lt;br /&gt;
странице HTML, а во-вторых, сохраняет текст в формате команды cat (в&lt;br /&gt;
этом формате гиперссылка выделяется повторением каждой буквы ее&lt;br /&gt;
надписи по два раза).&lt;br /&gt;
Помимо модулей KParts, браузер Konqueror поддерживает еще&lt;br /&gt;
несколько типов модулей. Модули панели навигации позволяют доба-&lt;br /&gt;
вить новые команды на панель навигации Konqueror (эта панель по&lt;br /&gt;
умолчанию припаркована к левому краю окна менеджера файлов).&lt;br /&gt;
Все, что требуется от модуля панели навигации – возвратить ука-&lt;br /&gt;
затель на визуальный элемент, который и будут отображен браузе-&lt;br /&gt;
ром при вызове соответствующей команды. Модули KFile позволяют&lt;br /&gt;
добавлять элементы в окно свойств файла (это окно можно вызвать с&lt;br /&gt;
помощью команды Свойства контекстного меню менеджера файлов).&lt;br /&gt;
Обычно модули KFile используются для вывода метаданных файлов.&lt;br /&gt;
Поскольку для всех мыслимых типов файлов такие модули уже напи-&lt;br /&gt;
саны, вам не придется писать модуль KFile, если только вы не разраба-&lt;br /&gt;
тываете собственный файловый формат.&lt;br /&gt;
&lt;br /&gt;
=== Модули KIPI ===&lt;br /&gt;
Структура модуля обычно настолько тесно связана со структурой&lt;br /&gt;
приложения, для которого этот модуль предназначен, что изучение&lt;br /&gt;
программирования модулей имеет смысл только в контексте изуче-&lt;br /&gt;
ния разработки для конкретного приложения. Однако из этого прави-&lt;br /&gt;
ла есть и исключения. Примером модулей, которые могут использо-&lt;br /&gt;
ваться для работы с несколькими разными приложениями, являются&lt;br /&gt;
модули KIPI. KIPI (KDE Image Plugin Interface – интерфейс KDE для&lt;br /&gt;
обработки изображений) – это проект, целью которого является&lt;br /&gt;
создание единого интерфейса модулей для основанных на KDE при-&lt;br /&gt;
ложений, предназначенных для просмотра и редактирования растро-&lt;br /&gt;
вых изображений, – Digikam, KimDaBa (ныне KPhotoAlbum), ShowFoto&lt;br /&gt;
и Gwenview. Хотя «KIPI» представляет собой аббревиатуру, на сайте&lt;br /&gt;
extragear.kde.org/apps/kipi/ используется написание «Kipi». Мы будем&lt;br /&gt;
писать KIPI, дабы читатели понимали, что это аббревиатура, а не рус-&lt;br /&gt;
ский глагол, написанный транслитом. Модули, соответствующие тре-&lt;br /&gt;
бованиям KIPI, должны работать одинаково во всех перечисленных&lt;br /&gt;
приложениях. Думаю, не нужно распространяться о том, насколько&lt;br /&gt;
это упрощает жизнь программиста, стремящегося к тому, чтобы его&lt;br /&gt;
разработками могли пользоваться поклонники всех графических&lt;br /&gt;
программ KDE. Конечно, не все модули могут иметь смысл в контекс-&lt;br /&gt;
те каждого приложения. Это становится очевидно, если учесть, что в&lt;br /&gt;
то время как одни приложения KDE (например, Gwenview) обладают&lt;br /&gt;
исключительно функциями просмотра, то другие (Digikam) включа-&lt;br /&gt;
ют еще и базовые функции редактирования. Если же все программы&lt;br /&gt;
будут эволюционировать в одном и том же направлении, система&lt;br /&gt;
утратит разнообразие и само наличие нескольких независимых про-&lt;br /&gt;
грамм потеряет смысл.&lt;br /&gt;
В отличие от других интерфейсов KDE, интерфейс KIPI сравнитель-&lt;br /&gt;
но слабо документирован. Это значит, что наилучшим источником све-&lt;br /&gt;
дений о программировании модулей KIPI являются исходные тексты&lt;br /&gt;
модулей, написанных другими программистами.&lt;br /&gt;
Информацию о модулях KIPI можно получить на сайте extragear.&lt;br /&gt;
kde.org. Там же можно загрузить и исходные тексты модулей (уже&lt;br /&gt;
модифицированные тексты вы можете найти на прилагаемом диске,&lt;br /&gt;
в файле kipi-plugins-0.1.2m.tar.gz). Прежде чем устанавливать модули&lt;br /&gt;
необходимо установить библиотеку libkipi (ее исходные тексты тоже&lt;br /&gt;
есть на диске, в файле libkipi-0.1.4.tar.bz2).&lt;br /&gt;
Рассмотрим структуру модуля KIPI на примере модуля HelloWorld,&lt;br /&gt;
который, как следует из названия, как раз и должен служить приме-&lt;br /&gt;
ром для начинающих модулеписателей (исходные тексты этого модуля&lt;br /&gt;
находятся в директории kipi-plugins-0.1.2/kipi-plugins/helloworld/ файла&lt;br /&gt;
kipi-plugins-0.1.2m.tar.gz). Как вы, наверное, догадались, модуль KIPI&lt;br /&gt;
представляет собой разделяемую библиотеку. Явным образом эта&lt;br /&gt;
библиотека экспортирует один-единственный класс – класс модуля.&lt;br /&gt;
Определение соответствующего класса Plugin_HelloWorld мы найдем в&lt;br /&gt;
файлах plugin_helloworld.cpp и plugin_helloworld.h.&lt;br /&gt;
Пробуем разобраться в том, что делает каждый метод этого класса.&lt;br /&gt;
Конструктор Plugin_HelloWorld вызывает конструктор базового класса&lt;br /&gt;
всех классов модулей KIPI KIPI::Plugin и выводит сообщение о том, что&lt;br /&gt;
модуль загружен. Отметим здесь, что поскольку модули подключаются&lt;br /&gt;
динамически, вывод такого сообщения полезен не только в процессе&lt;br /&gt;
отладки модуля. Рассмотрим метод setup(), который, как можно дога-&lt;br /&gt;
даться из названия, будет вызван приложением-хозяином модуля сра-&lt;br /&gt;
зу после создания объекта.:&lt;br /&gt;
void Plugin_HelloWorld::setup( QWidget* widget )&lt;br /&gt;
{&lt;br /&gt;
KIPI::Plugin::setup( widget );&lt;br /&gt;
// this is our action shown in the menubar/toolbar of the mainwindow&lt;br /&gt;
m_actionHelloWorld = new KAction (i18n(“Hello World...”),&lt;br /&gt;
“misc”,&lt;br /&gt;
0, // do never set shortcuts from plugins.&lt;br /&gt;
this,&lt;br /&gt;
SLOT(slotActivate()),&lt;br /&gt;
actionCollection(),&lt;br /&gt;
“helloworld”);&lt;br /&gt;
addAction( m_actionHelloWorld );&lt;br /&gt;
m_interface = dynamic_cast&amp;lt; KIPI::Interface* &amp;gt;( parent() );&lt;br /&gt;
if ( !m_interface )&lt;br /&gt;
{&lt;br /&gt;
kdError( 51000 ) &amp;lt;&amp;lt; “Kipi interface is null!” &amp;lt;&amp;lt; endl;&lt;br /&gt;
return;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
Этот метод вызывает одноименный метод базового класса и&lt;br /&gt;
создает объект-действие (таких объектов может быть зарегистриро-&lt;br /&gt;
вано несколько). В методе setup() модуль получает также указатель&lt;br /&gt;
на объект класса KIPI::Interface, который реализует интерфейс взаимо-&lt;br /&gt;
действия между модулем и программой-хозяином.&lt;br /&gt;
Далее в классе Plugin_HelloWorld определен метод slotActivate(),&lt;br /&gt;
который и выполняет всю работу модуля (именно этот слот был ука-&lt;br /&gt;
зан при создании объекта-действия). Метод slotActivate() мы пока&lt;br /&gt;
пропустим и рассмотрим последний метод класса Plugin_HelloWorld::&lt;br /&gt;
category():&lt;br /&gt;
KIPI::Category Plugin_HelloWorld::category( KAction* action ) const&lt;br /&gt;
{&lt;br /&gt;
if ( action == m_actionHelloWorld )&lt;br /&gt;
return KIPI::IMAGESPLUGIN;&lt;br /&gt;
kdWarning( 51000 ) &amp;lt;&amp;lt; “Unrecognized action for plugin category&lt;br /&gt;
identification” &amp;lt;&amp;lt; endl;&lt;br /&gt;
return KIPI::IMAGESPLUGIN; // no warning from compiler, please&lt;br /&gt;
}&lt;br /&gt;
С помощью этого метода программа-хозяин может выяснить, к&lt;br /&gt;
какой категории должен принадлежать элемент управления, кото-&lt;br /&gt;
рый она создает для данного объекта-действия. Модуль HelloWorld&lt;br /&gt;
возвращает значение KIPI::IMAGESPLUGIN, которое указывает, что&lt;br /&gt;
соответствующий элемент управления должен относиться к катего-&lt;br /&gt;
рии Images.&lt;br /&gt;
Для того чтобы написать свой модуль KIPI, нам, фактически, необхо-&lt;br /&gt;
димо только переписать метод slotActivate() модуля HelloWorld. В архиве&lt;br /&gt;
kipi-plugins-0.1.2m.tar.gz вы найдете модуль mykipi, который и был создан&lt;br /&gt;
на основе модуля HelloWorld (поскольку заготовки проекта KDevelop для&lt;br /&gt;
такого модуля в KDevelop нет, его проще распространять как часть паке-&lt;br /&gt;
та kipi-plugins). Все, что отличает модуль mykipi от модуля-прародителя,&lt;br /&gt;
сосредоточено в методе slotActivate() класса Plugin_MyKIPI:&lt;br /&gt;
void Plugin_MyKIPI::slotActivate()&lt;br /&gt;
{&lt;br /&gt;
kdDebug( 51000 ) &amp;lt;&amp;lt; “Plugin_MyKIPI slot activated” &amp;lt;&amp;lt; endl;&lt;br /&gt;
KIPI::ImageCollection selection = m_interface-&amp;gt;currentSelection();&lt;br /&gt;
if ( !selection.isValid() ) {&lt;br /&gt;
kdDebug( 51000) &amp;lt;&amp;lt; “No Selection!” &amp;lt;&amp;lt; endl;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
KURL::List images = selection.images();&lt;br /&gt;
QStringList SL = images.toStringList();&lt;br /&gt;
QString S = SL.join(“\n”);&lt;br /&gt;
KMessageBox::information(0, S, “Selected Images”);&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
Метод начинает работу с вывода диагностического сообщения.&lt;br /&gt;
Затем мы создаем объект класса KIPI::ImageCollection, который содер-&lt;br /&gt;
жит ссылки на объекты, представляющие изображения, выбранные&lt;br /&gt;
пользователем в окне графической программы (ваш разум еще не&lt;br /&gt;
кипит от этих модулей KIPI?). Если метод currentSelection() вернул зна-&lt;br /&gt;
чение NULL, значит, пользователь не выбрал ни одного изображения&lt;br /&gt;
и тогда нашему модулю просто нечего делать. Впрочем, вызов модуля&lt;br /&gt;
при отсутствии выбранных изображений невозможен, как невозможен&lt;br /&gt;
вызов модуля KParts для неподходящего компонента. Как и положено&lt;br /&gt;
всякому учебному примеру, модуль mykipi не делает ничего полезного.&lt;br /&gt;
С помощью метода selection.images() мы получаем список URL выде-&lt;br /&gt;
ленных изображений (не забывайте, что мы имеем дело с программа-&lt;br /&gt;
ми, предназначенными, в основном, для просмотра и редактирования&lt;br /&gt;
существующих графических файлов). Далее мы преобразуем список&lt;br /&gt;
URL в QStringList и затем QString, и выводим его содержимое в диа-&lt;br /&gt;
логовом окне.&lt;br /&gt;
&lt;br /&gt;
Когда я писал, что у нашего модуля есть только один класс, я&lt;br /&gt;
немного упростил ситуацию. На самом деле, модуль реализует еще&lt;br /&gt;
один класс, а именно класс Factory, управляющий созданием основного объекта класса модуля, однако генерация этого класса выполняется&lt;br /&gt;
автоматически с помощью определения типа и вызова макроса:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp-qt&amp;quot;&amp;gt;typedef KGenericFactory&amp;lt;Plugin_MyKIPI&amp;gt; Factory;&lt;br /&gt;
K_EXPORT_COMPONENT_FACTORY( kipiplugin_mykipi,Factory(&amp;quot;kipiplugin_mykipi&amp;quot;));&amp;lt;/source&amp;gt;&lt;br /&gt;
Прежде, чем мы установим наш модуль, нам следует отредактировать файл kipiplugin_mykipi.desktop. Ниже приводится его отредактированный текст (структура файлов *.desktop похожа на структуру файлов *.ini Windows, и это не случайное совпадение):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;ini&amp;quot;&amp;gt;[Desktop Entry]&lt;br /&gt;
Encoding=UTF-8&lt;br /&gt;
Name=MyKIPI&lt;br /&gt;
Name[cs]=My KIPI&lt;br /&gt;
Comment=Sample KIPI Plugin&lt;br /&gt;
Type=Service&lt;br /&gt;
ServiceTypes=KIPI/Plugin&lt;br /&gt;
X-KDE-Library=kipiplugin_mykipi&lt;br /&gt;
author=Andrei Borovsky, borovsky@tochka.ru&amp;lt;/source&amp;gt;&lt;br /&gt;
[[Изображение:Img 84 75 1.jpg|thumb|(Рис. 3) Модуль mykipi в работе.]]&lt;br /&gt;
Файл kipiplugin_mykipi.desktop cодержит сведения о типе модуля&lt;br /&gt;
(ServiceTypes=KIPI/Plugin), а также имя модуля и комментарий.&lt;br /&gt;
&lt;br /&gt;
Теперь мы можем скомпилировать и установить модуль (естественный путь – make install). Запустим программу Gwenview и в меню&lt;br /&gt;
Модули, в группе Изображения (Images) мы увидим команду Sample&lt;br /&gt;
KIPI Plugin, которая будет работать так, как мы и ожидаем (Рис. 3).&lt;br /&gt;
&lt;br /&gt;
В этой статье мы рассмотрели, среди прочих, модули для компонентов KParts. В следующей, заключительной части серии мы узнаем,&lt;br /&gt;
как создавать собственные компоненты (и модули для них).&lt;/div&gt;</description>
			<pubDate>Sun, 14 Dec 2008 14:08:50 GMT</pubDate>			<dc:creator>Yaleks</dc:creator>			<comments>http://wiki2.linuxformat.ru/index.php/%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5:LXF84:Qt/KDE</comments>		</item>
	</channel>
</rss>