Есть необходимость создать систему расширений для приложения на PyQt4. Требуется, чтобы они могли что-либо добавлять в окно/диалоги программы, выводить сообщения на её трей. Не могу представить, как реализовать подобную архитектуру :/ Есть идеи?
Начать, наверное, стоит и изучения Qt4. А если точнее, системы плагинов, которая там присутствует. Но это так, для общего развития... Ибо в питоне есть такая функция -- __import__, и с помощью неё я создал у себя динамическую систему плагинов (а если точнее пакетов, но принцип тот же).
Что нужно? Определится с API плагинов. Он вытекает из требуемой функциональности. А дальше импортируешь класс-плагин (например от QObject, или сразу QDialog), создаёшь объект с родителем -- плагин-менеджером и... дальше сам разбирёшься. Ничего, впринципе, сложного.
P.S. И не забудь про reload, а то я как-то по-парился...
Что нужно? Определится с API плагинов. Он вытекает из требуемой функциональности. А дальше импортируешь класс-плагин (например от QObject, или сразу QDialog), создаёшь объект с родителем -- плагин-менеджером и... дальше сам разбирёшься. Ничего, впринципе, сложного.
P.S. И не забудь про reload, а то я как-то по-парился...
...так кто ж ты, наконец?
-- Я -- часть той силы, что вечно хочет зла
и вечно совершает благо.
-- Я -- часть той силы, что вечно хочет зла
и вечно совершает благо.
Реализовал таки систему плагинов, но оно не работает так, как задумывалось =\
Итак, есть базовый класс Plugin:
В менюшке Plugins в программе появляются, но нажатие на них не приводит ни к чему, хотя, по идее, должен выполняться метод do =\
Итак, есть базовый класс Plugin:
# Copyright (C) 2007-2008 GFORGX <gforgx@gmail.com>
# Distributed under the terms of revised BSD license.
from PyQt4 import QtCore, QtGui
class Plugin(QtCore.QObject):
def __init__(self, main):
self.setObjectName("Plugin")
self.main = main
self.icon = "/usr/share/notefinder/note.png"
self.action = 'Does nothing'
def load(self):
action = QtGui.QAction(QtGui.QIcon(self.icon), QtGui.QApplication.translate("Plugin", self.action, None, QtGui.QApplication.UnicodeUTF8), self.main)
self.main.ui.menuPlugins.addAction(action)
self.connect(action, QtCore.SIGNAL("triggered()"), self.do)
def currentNote(self):
list = self.main.ui.notesList
index = list.currentRow()
item = list.item(index)
if not item is None:
note = str(item.text().toUtf8())
return note
def do(self):
passЕсть плагин, например:# Copyright (C) 2008 GFORGX <gforgx@gmail.com>
# Distributed under the terms of revised BSD license.
from notefinder import plugin
from libnofi import Note
from PyQt4 import QtGui
from datetime import datetime
class ClipboardCapture(plugin.Plugin):
def __init__(self, main):
self.main = main
self.action = "Capture clipboard"
self.icon = "/usr/share/notefinder/paste.png"
def do(self):
cb = QtGui.QApplication.clipboard()
text = str(cb.text().toUtf8())
name = 'New note %s' % (datetime.strftime(datetime.today(),'%Y-%m-%d-%H:%M:%S'))
note = Note(name)
note.write(text)Программа грузит это так (через egg entry points):# Copyright (C) 2008 GFORGX <gforgx@gmail.com>
# Distributed under the terms of revised BSD license.
import pkg_resources
for ep in pkg_resources.iter_entry_points('notefinder.plugins'):
plugin = ep.load()
plug_in = plugin(main)
plug_in.load()Т. е. плагину при инициализации в качестве аргумента передаётся основное окно программы.В менюшке Plugins в программе появляются, но нажатие на них не приводит ни к чему, хотя, по идее, должен выполняться метод do =\
Last edited July 3, 2008, 12:55 p.m.
В общем, судя по всему, проблема в том, что вот тут:
action = QtGui.QAction(QtGui.QIcon(self.icon), QtGui.QApplication.translate("Plugin", self.action, None, QtGui.QApplication.UnicodeUTF8), self.main)
я указываю в качестве последнего параметра окно программы, а не сам объект плагин.
Если заменяю self.main на self - то:
action = QtGui.QAction(QtGui.QIcon(self.icon), QtGui.QApplication.translate("Plugin", self.action, None, QtGui.QApplication.UnicodeUTF8), self.main)
я указываю в качестве последнего параметра окно программы, а не сам объект плагин.
Если заменяю self.main на self - то:
[gforgx@ffap ~]$ notefinder
Traceback (most recent call last):
File "/usr/bin/notefinder", line 45, in <module>
plug_in.load()
File "/usr/lib/python2.5/site-packages/notefinder/plugin.py", line 43, in load
action = QtGui.QAction(QtGui.QIcon(self.icon), self.action, self)
RuntimeError: underlying C/C++ object has been deleted