Вопрос

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

Это было полезно?

Решение

Во-первых, используйте Qfiledialog. или удобнее статическая функция Qfiledialog.getopenfilename. Чтобы пользователю выбрать .py Файл, который они хотят «подключить» к вашему графическому интерфейсу.

Далее, если вы хотите позволить импортировать плагин из в любом месте на диске (в отличие от конкретных каталогов, ранее добавленных к вашему 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, & 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.

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

Другие советы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top