The OpenNET Project / Index page

[ новости/++ | форум | wiki | теги ]

Поддержка плагинов в программах на Python (python plugin module)


<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>
Ключевые слова: python, plugin, module,  (найти похожие документы)
From: Вадим Хохлов <http://www.selena.kherson.ua/xvadim>; Date: Sun, 30 Mar 2008 17:02:14 +0000 (UTC) Subject: Поддержка плагинов в программах на Python Оригинал: http://gazette.linux.ru.net/rus/articles/pyplug.html Введение -------- В настоящее время множество программ поддерживают работу с плагинами (дополнительными модулями). Такая поддержка позволяет делать программы более гибкими и расширяемыми. В качестве примера можно привести известный медиапроигрыватель XMMS. Существует библиотека dl, которая используется при разработке программ, поддерживающих механизм плагинов. О ее применении можно узнать из статьи "Добавление модулей расширения (плагинов) к программе", автор Tom Bradley. В данной статье будет рассмотрен метод работы с плагинами в программах на Python. Теория Язык Python имеет встроенную поддержку модулей. В стандартную библиотеку Python'а входит множество модулей, содержащих функции для работы с операционной системой, протоколами и форматами, активно используемыми в сети Интернет, строками, базами данных и т.п. Для подключения модулей в программу (которая тоже не что иное как модуль) используется инструкция import. Например, следующая строка загружает модуль fibo, который находится в файле fibo.py (пример взят из книги "Язык программирования Python"): import fibo При импорте модулей интерпретатор ищет файл с соответствующим именем в текущем каталоге, затем в каталогах, которые указанны в переменной PYTHONPATH, затем в путях по умолчанию (переменная окружения PATH). Большинство программ на Python начинаются со строк, в которых с помощью данной инструкции и ее вариантов загружаются необходимые модули. Имеется также возможность определить имя модуля динамически во время работы программы и загрузить его с помощью встроенной функции __import__. Постановка задачи Пусть необходимо разработать программу, которая в зависимости от подключенного плагина показывает в главном окне различные органы управления: checkbox's plugin radiobutton's plugin Плагин должен выбираться с помощью выпадающего списка. При нажатии на кнопку "get info" на экран будет выводиться некоторая информация о состоянии текущего плагина. Решение Сначала напишем модули плагинов. Будем использовать PyQt для создания интерфейсных элементов. Ниже представлен модуль, создающий окно с переключателем checkbox и меткой: #! /usr/bin/python import sys, os import qt def getPluginWidget(parent): return PluginWidgetCheck(parent) class PluginWidgetCheck(qt.QWidget): def __init__(self, parent = None): qt.QWidget.__init__(self, parent, "ConfigWidget") topLayout = qt.QVBoxLayout(self, 0, 0, "topLayout") self.lb = qt.QLabel("label", self) topLayout.addWidget(self.lb) self.rb = qt.QCheckBox("test", self) topLayout.addWidget(self.rb) self.connect(self.rb, qt.SIGNAL("clicked()"), self.slotClick) def slotClick(self): if (self.rb.isChecked()): self.lb.setText("checked") else: self.lb.setText("unchecked") def getInfo(self): if (self.rb.isChecked()): return "checkbox is checked" else: return "checkbox is unchecked" if __name__ == "__main__": app = qt.QApplication(sys.argv) pluginWidget = PluginWidgetCheck() app.setMainWidget(pluginWidget) pluginWidget.show() app.exec_loop() Вот модуль с окном, которое содержит однострочный редактор и переключатель radiobutton: #! /usr/bin/python import sys, os import qt def getPluginWidget(parent): return PluginWidgetRadio(parent) class PluginWidgetRadio(qt.QWidget): def __init__(self, parent = None): qt.QWidget.__init__(self, parent, "ConfigWidget") topLayout = qt.QVBoxLayout(self, 0, 0, "topLayout") self.rb = qt.QRadioButton("test", self) topLayout.addWidget(self.rb) self.le = qt.QLineEdit(self) topLayout.addWidget(self.le) self.connect(self.rb, qt.SIGNAL("clicked()"), self.slotRadio) def slotRadio(self): if (self.rb.isChecked()): self.le.setText("checked") else: self.le.setText("unchecked") def getInfo(self): if (self.rb.isChecked()): return "radiobutton is checked" else: return "radiobutton is unchecked" if __name__ == "__main__": app = qt.QApplication(sys.argv) pluginWidget = PluginWidgetRadio() app.setMainWidget(pluginWidget) pluginWidget.show() app.exec_loop() Оба модуля содержат функцию getPluginWidget, возвращающую виджет, который будет размещен в окне. У данного виджета есть метод getInfo, возвращающий информацию о его состоянии. Обратите внимание на следующий фрагмент: if __name__ == "__main__": app = qt.QApplication(sys.argv) pluginWidget = PluginWidgetRadio() app.setMainWidget(pluginWidget) pluginWidget.show() app.exec_loop() Переменная __name__ содержит имя модуля. Если же модуль запускается из командной строки, а не импортируется, эта переменная имеет значение __main__. Используя подобный фрагмент, можно выполнить отладку модуля отдельно и только потом его импортировать в программу. Теперь рассмотрим текст программы: #! /usr/bin/python import sys, os import qt class MainWidget(qt.QWidget): def __init__(self, parent = None): qt.QWidget.__init__(self, parent, "ConfigWidget") topLayout = qt.QVBoxLayout(self, 0, 0, "topLayout") self.cb = qt.QComboBox(0, self) topLayout.addWidget(self.cb) self.cb.insertItem("radio") self.cb.insertItem("check") self.gb = qt.QVGroupBox("conf", self) topLayout.addWidget(self.gb) self.pb = qt.QPushButton("get info", self) topLayout.addWidget(self.pb) self.toolWin = None self.connect(self.cb, qt.SIGNAL("activated(const QString&)"), self.slotToolChanged) self.connect(self.pb, qt.SIGNAL("clicked()"), self.slotGetInfo) self.slotToolChanged("radio") def slotToolChanged(self, toolName): toolName = str(toolName) if (sys.modules.has_key(toolName)): module = reload(sys.modules[toolName]) else: module = __import__(toolName, globals()) if(self.toolWin is not None): self.toolWin.close() self.toolWin = module.getPluginWidget(self.gb) self.toolWin.show() def slotGetInfo(self): print "info:" + self.toolWin.getInfo() app = qt.QApplication(sys.argv) mainWidget = MainWidget() app.setMainWidget(mainWidget) mainWidget.show() app.exec_loop() Загрузка плагинов выполняется в методе slotToolChanged. Сначала мы проверяем, загружался ли модуль ранее. Если да, то заново его считываем и инициализируем с помощью функции reload. Иначе модуль импортируется функцией __import__. После загрузки модуля внутри groupbox'а создается окно плагина. Так как эта программа создавалась лишь с демонстрационными целями, я намеренно не добавлял обработку ошибок. Заключение Таким образом, встроенные возможности Python'а позволяют довольно легко разрабатывать программы, поддерживающие механизм плагинов. Об авторе Я работаю программистом и преподаю в Херсонском государственном техническом университете. С Linux знаком с 1999 года. Общаюсь с ним, в основном, дома. Кроме этого, я являюсь разработчиком IceWM Control Center - набора программ (в том числе и скриптов icerrun) для настройки различных параметров IceWM.

<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>

Ваш комментарий
Имя:         
E-Mail:      
Заголовок:
Текст:





  Закладки на сайте
  Проследить за страницей
Created 1996-2017 by Maxim Chirkov  
ДобавитьРекламаВебмастеруГИД  
Hosting by Ihor