可插入python程序
题
我想制作一个支持插件的PYQT4程序。基本上,我希望用户能够在PYQT4中编写Qwidget子类,并通过GUI从主应用程序窗口中添加/将其删除。我该怎么做,尤其是插件机制?
解决方案
首先,使用 qfiledialog 或更方便地静态功能 qfiledialog.getopenfilename 让用户选择 .py
他们想“插入”您的GUI。
接下来,如果要允许从 任何地方 在磁盘上(而不是从先前添加到您的特定目录中 sys.path
, ,例如通过环境变量 PYTHONPATH
),您可以通过 小鬼 标准python库中的模块),或者您可以按下“砍伐”(假设 filepath
是个 QString
有了通往文件的路径,并且您使用的是带有本地unicode文件名的文件系统/平台 - 否则您必须添加所有内容 .encode
您的平台和文件系统需要)...:
import sys, os
def importfrom(filepath):
ufp = unicode(filepath)
thedir, thefile = os.path.split(ufp)
if sys.path[0] != thedir:
sys.path.insert(0, thedir)
themodule, theext = os.path.splitext(thefile)
return __import__(themodule)
这不是线程安全,因为它可能对 sys.path
, ,这就是为什么我说这是“割伤的角落” ...但是然后,进行线程安全进口(和从“任何地方”进口)是 真的 努力工作(如果需要的话,可能值得一个单独的问题,因为这与该要旨或PYQT等要点无关。
一旦您拥有模块对象(来自 importfrom
上面),我建议:
from PyQt4 import QtGui
import inspect
def is_widget(w):
return inspect.isclass(w) and issubclass(w, QtGui.QWidget)
def all_widget_classes(amodule):
return [v for n, v in inspect.getmembers(amodule, is_widget)]
这将返回所有小部件的列表 课程 (如果有)在模块中定义(在顶级) amodule
.
当然,您要做的接下来要做的是由您决定。也许您要提供某种错误消息,如果列表为空(或者也有一个以上的项目,或者还要决定使用哪个窗口小部件类?),或者如何实例化窗口小部件类(多少次?在什么坐标?等等 - 等等 - 只有您可以回答的问题),并在窗口上适当的位置显示所得的小部件。
其他提示
具有插件的目录,为这些插件定义接口,然后在导入它们的目录中行走。
我从来没有在Python中执行此操作,但是在C我这样做的方式是定义插件需要实现的许多功能。必要的基本密钥元素是插件中事物的名称(因此您可以在UI中显示它们,以便用户可以实例化它们)和一个工厂来实际创建事物。我想在python中,只要做一个可以从模块中返回的事情,这是很微不足道的。
例如,声明所有插件都必须撰写一个名为getPlugininfo()的函数,该函数返回名称字典:类映射。
实际上,现在我考虑了它,您可能只能导入文件,并查找是您关心的任何类别且不需要实现任何明确API的类。我没有做很多事情,但是基本上您会走模块的dir()并测试以查看每件事是否是Qwidget的子类(例如)。