我想制作一个支持插件的PyQt4程序。基本上,我希望用户能够在 PyQt4 中编写 QWidget 子类,并通过 GUI 从主应用程序窗口添加/删除它们。我该怎么做,特别是插件机制?
最佳答案
首先,使用 QFileDialog或者更方便地使用静态函数 QFileDialog.getOpenFileName让用户选择他们想要“插入”您的 GUI 的 .py
文件。
接下来,如果您希望允许从磁盘上的任何地方导入插件(而不是从之前添加到sys.path
的特定目录,例如通过环境变量 PYTHONPATH
),您可以通过 imp “做对”(不可忽略的工作量)标准 Python 库中的模块),或者您可以按如下方式“偷工减料”(假设 filepath
是带有文件路径的 QString
,并且您正在使用具有 native 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 的要点没有太大关系) ,&c)。
一旦你有了模块对象(上面 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 - 可插入的Python程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3588915/