Сменная программа Python - PullRequest
       7

Сменная программа Python

2 голосов
/ 28 августа 2010

Я хочу сделать программу PyQt4, которая поддерживает плагины.По сути, я хочу, чтобы пользователь мог писать подклассы QWidget в PyQt4 и добавлять / удалять их из главного окна приложения через графический интерфейс.Как бы я это сделал, особенно механизм плагинов?

Ответы [ 2 ]

6 голосов
/ 28 августа 2010

Во-первых, используйте QFileDialog или более удобно статическую функцию QFileDialog.getOpenFileName , чтобы позволить пользователю выбрать файл .py, который он хочет "подключить" к вашему графическому интерфейсу.

Далее, если вы хотите разрешить импорт плагина из в любое место на диске (в отличие от определенных каталогов, ранее добавленных к вашему sys.path, например, через переменную окружения PYTHONPATH), вы можете «сделать это правильно» (немалый объем работы) через модуль imp в стандартной библиотеке 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, & 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.

Что вы хотите сделать дальше, конечно, зависит от вас. Возможно, вы хотите выдавать какие-то сообщения об ошибках, если список пуст (или, может быть, если в нем более одного элемента? Или как решить, какой класс виджетов использовать?) Или создать экземпляр класса виджетов (сколько раз? По каким координатам? И так далее - вопросы, на которые только вы можете ответить) и отобразить полученные виджеты в соответствующих местах в вашем окне.

0 голосов
/ 28 августа 2010

Иметь каталог для плагинов, определить интерфейс для этих плагинов и пройтись по каталогу, импортирующему их.

Я никогда не делал этого в Python, но в Си так, как я это сделал, было определитьряд функций, которые плагин должен был реализовать.Основными ключевыми элементами, которые необходимы, являются имена вещей в плагине (чтобы вы могли отображать их в своем пользовательском интерфейсе, чтобы пользователь мог их создавать) и фабрика для фактического создания вещей.Я предполагаю, что в Python было бы довольно тривиально просто сделать это как один диктовку, которую можно вернуть из модуля.

Например, объявить, что все плагины должны создавать функцию GetPluginInfo (), которая возвращает словарь имен: сопоставления классов.

На самом деле, теперь, когда я думаю об этом, вы, вероятно, можете просто импортировать файл и искать классы, которые являются подклассами того, что вас волнует и не требуют реализации какого-либо явного API.Я не сделал этого много, но в основном вы должны пройти модуль dir () и проверить, является ли каждая вещь подклассом QWidget (например).

...