====== Быстрый старт ======
Данная статья написана для разработчиков, в ней будет описан процесс разработки плагина на платформе PUSSY. Разработчик должен обладать знаниями и навыками разработки на Python и Qt, в данном случае будет использована привязка к инструментам Qt - PySide6.
===== Пишем свой плагин =====
О концепции Плагина читайте в [[:products:pussy:concepts:plugin|статье]]. Если говорить коротко, то плагин это просто набор скриптов Python (пакет), который обязан иметь собственный графический интерфейс, в данном случае это класс виджета, который встраивается в окно Менеджера, за этим интерфейсом может скрываться совершенно любая реализация.
Для работы нам потребуется:\\
* Python3;
* PySide6;
* Инструмент для написания кода (я предпочитаю IDE [[:products:pussy:other:main|PyCharm]]);
* [[https://github.com/iron-mesh/utilities-box|исходный код PUSSY]] .
В [[:products:pussy:other:pycharm|PyCharm]] создайте новый проект, добавьте в нее папку PUSSY, и пометьте **[[:products:pussy:other:pyub|PyUB]]** как **Source Root**, чтобы иметь возможность импортировать модули из данного пакета.
{{ :products:pussy:screenshots:projectstructinpycharm.jpg?400 |projectstructinpycharm.jpg}}
==== Пишем код ====
Сделаем пробный плагин - кодовый замок, конечно, это просто игрушка для демонстрации и никаких полезных функций он не делает, но для объяснения основ сгодится.
Описание алгоритма: код от «замка» устанавливается через настройки, если код введен верно, то поле загорается зелеными, иначе – красным, поле блокируется на несколько секунд.
Посмотрим на плагин в общих чертах, по сути это пакет Python - папка, содержащая файл // _ _init. py_ _//, размещается она в папке **manager/Plugins**, либо во внешних директориях, указанных в настройках. В папке **Plugins ** есть шаблон (папка **Template**), скопируйте его, когда будете писать свой плагин, переименуйте папку и файлы как посчитаете нужным.
//Внимание! Пакеты с именем //**// Template // **//игнорируются при загрузке.//
В нашем случае плагин будет разделен на 4 файла (в исходные файлы находятся в **Plugins/Codelock**): //_ _ init_ _.py// – здесь будет производится регистрация класса с интерфейсом и размещается дополнительная информация, ничего более тут выполнять не нужно; //View.py// – здесь определен главный класс интерфейса; //Settings.py// – класс с настройками; //ui_ form.py// – код виджета, сгенерированный в [[:products:pussy:other:qtdesigner|QtDesigner]]. В зависимости от сложности плагина и предпочтений разработчиков структура может быть любая, но в каждом случае в файле //_ _init.py_ _ // должна производиться регистрация виджета плагина.
Так выглядит код //View.py//:
from PyUB.Types import UBWidget
from PySide6.QtWidgets import QPushButton
from .ui_form import Ui_Form
from .Settings import Settings
class CodeLock(UBWidget):
ub_settings = Settings
def __init__(self):
super().__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)
self._init_gui()
self._code = self.ub_settings.get_property_value("code")
def _init_gui(self):
for name in dir(self.ui):
attr = getattr(self.ui, name)
if type(attr) is QPushButton:
attr.clicked.connect(self.on_btn)
self.ui.lineEdit.setStyleSheet("")
self.ui.lineEdit.textChanged.connect(self.text_changed)
self.ui.lineEdit.setInputMask(self.ub_settings.get_property("code").p_input_mask)
def on_btn(self):
if not self.ui.lineEdit.isEnabled(): return
s = self.sender()
self.ui.lineEdit.setText(self.ui.lineEdit.text() + s.text())
def text_changed(self, text):
if len(text) == len(self._code):
if text == self._code:
self.ui.lineEdit.setStyleSheet(u"background-color: rgb(85, 255, 127);")
else:
self.ui.lineEdit.setStyleSheet(u"background-color: rgb(240, 54, 8);")
self.ui.lineEdit.setEnabled(False)
self.id = self.startTimer(5000)
def timerEvent(self, event) -> None:
self.ui.lineEdit.setStyleSheet("")
self.ui.lineEdit.clear()
self.ui.lineEdit.setEnabled(1)
self.killTimer(self.id)
def settings_edit_finished(self, changed:bool) -> None:
if not changed: return
self._code = self.ub_settings.get_property_value("code")
self.ui.lineEdit.clear()
В данном коде определен класса интерфейса, также в нем описана вся логика программы, для крупных программ так делать не рекомендуется. Этот класс унаследован от **UBWidget ** и его экземпляр будет встраиваться в окно Менеджера в качестве вкладки. Код в методе //_ _init_ _ () // выполняется, когда пользователь перешел во вкладку, в которой размещается экземпляр данного класса, или при запуске Менеджера, если пользователь ранее активировал параметр «Инициализировать при запуске» (init on startup).
В данном варианте бы определили следующие атрибуты и методы:
Поля класса:
* //ub_ //// settings //- (опционально) ссылка на класс с пользовательскими настройками (потомок **[[:products:pussy:other:propertycontainer|PropertyContainer]]**), в нашем случае это класс **[[:products:pussy:other:mysettings|Settings]]**.
Методы:
* //__init__ ( //// self) //- инициализация виджета, в данном случае тут производится встраивание интерфейса, сгенерованного с помощью [[:products:pussy:other:qtdesigner|QtDesigner]];
* //settings_ //// edit_ //// finished ( //// self, //// changed: //// bool) //– (выполняется после завершения редактирования настроек, changed принимает значения: True – если хотя бы одно из свойств было изменено, иначе – False), если пользователь изменил код замка, то производится обновления поля //_code//, поле ввода очищается.
Подробнее о **UBWidget** [[:products:pussy:api:pyub:types:ubwidget|здесь]] .
Перейдем к файлу с настройками ( //Settings.py//). Его код :
from PyUB.Types import PropertyContainer
from PyUB.Types.Properties import StringProperty
class Settings(PropertyContainer):
code: StringProperty(default_value="12345", input_mask="00000000", name="Код")
Тут определено всего одно свойство для ввода строки. Подробнее о контейнере свойств и самих свойствах смотрите в материалах: [[:products:pussy:concepts:property|]], [[:products:pussy:concepts:propertycontainer|]], [[:products:pussy:api:pyub:types:propertycontainer|]].
Итак, все важные классы мы уже определили, теперь нужно сообщить Менеджеру какой класс нужно устанавливать. Для этого в модуле //[[:products:pussy:api:pyub:utils|]]// есть функция //register_ubwidget()//, в нее надо передать ссылку на класс-потомок **UBWidget**, в плагине можно зарегистрировать только один класс, это действие нужно выполнить в файле //_ _init.py_ _//. Также в этом файле по желанию можно определить дополнительную информацию о плагине, создать переменную //ub_info// ={…}, это типичный словарь, допускаются ключи и значения только строкового типа, в таблице ниже показан пример оформления, некоторые пункты могут быть исключены по желанию.
| |**Ключ** |**Пример значения** |**Описание** |
|1 |description |“Этот плагин выводит спутник на орбиту”|Описание плагина. Дайте емкое и лаконичное описание плагина. Например, для чего он предназначен и т.д.|
|2 |author |"Иван Иванов"|Имя автора|
|3 |author_webpage |“[[http://www.ironmesh.ru|www.ironmesh.ru]]” |Веб-страница автора|
|4 |author_email |“ivan_ivanov@mail.com” |Адрес электронной почты автора|
|5 |version |“1.3.4” |Версия плагина|
|6 |wiki_url |“ivan_ivanov.wiki.com” |Ссылка на страницу вики|
Подведем итоги. В данной статье я дал необходимы сведения касательно разработки собственных плагинов, как вы можете убедиться, в этом нет ничего сложного, при наличии опыта разработки с применение перечисленных технологий. Более подробную информацию ищите в других разделах вики. Если что-то осталось неясным, то можете задать свои вопросы в [[https://discord.gg/JD5yKPrKCk|Discord]].