2

我想做一个支持插件的 PyQt4 程序。基本上我希望用户能够在 PyQt4 中编写 QWidget 子类,并通过 GUI 从主应用程序窗口中添加/删除它们。我该怎么做,尤其是插件机制?

4

2 回答 2

6

首先,使用QFileDialog或更方便的静态函数QFileDialog.getOpenFileName让用户选择.py他们想要“插入”您的 GUI 的文件。

接下来,如果您想允许从磁盘上的任何位置导入插件(而不是从以前添加到您的特定目录sys.path,例如通过环境变量PYTHONPATH),您可以“正确执行”(不可忽略的工作量),通过标准 Python 库中的imp模块),或者您可以按如下方式“偷工减料”(假设filepathQString文件路径,并且您正在使用具有本机 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)]

这将返回一个列表,其中包含在 module 中定义(在顶层)的所有小部件amodule(如果有) 。

当然,接下来你想做什么取决于你。如果列表为空(或者如果它有多个项目?或者如何决定使用哪个小部件类?)或者实例化小部件类(多少次?在什么坐标?等等——只有你可以回答的问题)并在窗口的适当位置显示生成的小部件。

于 2010-08-28T02:29:16.113 回答
0

为插件创建一个目录,为这些插件定义一个接口,然后通过目录导入它们。

我从来没有在 Python 中这样做过,但是在 C 中我这样做的方式是定义插件需要实现的许多函数。必要的基本关键元素是插件中事物的名称(以便您可以在 UI 中显示它们,以便用户可以实例化它们)和实际创建事物的工厂。我想在 Python 中,将它们作为一个可以从模块返回的 dict 来做是非常微不足道的。

例如,声明所有插件都必须编写一个名为 GetPluginInfo() 的函数,该函数返回名称:类映射的字典。

实际上,现在我考虑一下,您可能只需导入文件并查找作为您关心的任何子类的类,并且不需要实现任何显式 API。我没有做很多,但基本上你会走模块的 dir() 并测试每个东西是否是 QWidget 的子类(例如)。

于 2010-08-28T00:37:29.470 回答