# ease plugin tools **Repository Path**: XBCoder/ease-plugin-tools ## Basic Information - **Project Name**: ease plugin tools - **Description**: 一个简单的插件管理模块 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-08-05 - **Last Updated**: 2021-08-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ease plugin tools #### 介绍 一个简单的插件管理模块 #### 使用说明 导入并使用: ```python from ease_plugin.plugin import Plugin args = { 'args': (100, 200), 'kwargs': {'version': '1.0.1'} } p = Plugin('PluginDir', args) ``` 其中,`args`为传递给初始化插件函数的参数,`Plugin`的构造参数为:`def __init__(self, plugin_dir, plugin_init_args=None):` #### 插件说明 在本系统中,一个插件为一个存放在目录`plugin_dir`下包含文件`plugin.py`的**文件夹**: ![image-20210806230534864](C:\Users\XBCoder\AppData\Roaming\Typora\typora-user-images\image-20210806230534864.png) 并且plugin中必须包含`Init`函数,如下是一个示例: ```python from . import function # 导入同目录的模块必须这么写 def Init(a, b, version=""): # 此处是插件系统传递给插件初始化函数的参数,见上方的args print("Hello World!!!") print(a, b, version) return None ``` 一般来说,Init函数应当返回一个`dict`,表示插件的回调函数,这些回调函数可以通过插件系统获得并在合适的地方调用:而回调函数的定义需要项目作者去定制,本插件系统只负责维护,但是其中一个函数:`Delete`,也就是插件的析构函数,是固定的。 如下是一个合法的插件(作者以前写课程项目搞的): ```python ''' 每个插件需要实现 Init 函数,函数返回为一个字典, 字典中包含各方法以及对应的回调函数,若不提供某功能则放置 None即可 字典的定义如下: callback = { 'RecvMethod': func2(msg), # 收到消息要执行的事件 'SendMethod': func3(msg), # 收到消息后要执行的事件 'Delete' : delete() # 用于在插件即将被关闭时处理事件 'GetUsefulFunc': func5({...}) 获取有用的可调用函数,如发送消息函数 'AddingItemFunc': func6(Widget) # 在添加表项时被调用,为什么设置 这个呢?因为想搞一个头像插件。。。 'SetupUI' : SetupUi(Widgets) ... } 关于函数返回,暂定返回1个bool, 表示是否希望将结果交给后续插件处理 (比如当前消息并非本插件需要处理的信息,则返回False),commandSet 除外 除了 Init 函数以外,插件还可以定义 Delete 函数,当插件被关闭时 可以进行一些必要的保存操作等等,Delete函数也应当放在上述的字典中 插件可以在主窗口上进行UI设置,定义函数 SetupUi(Widgets),可获得 可以修改或取值的一些控件: PlugWidgets = { 'menuBar': self.menuBar, 'BottomToolBar': self.ToolBarLayout, 'MsgEdit': self.MsgEditView, 'LeftTabView':self.tabWidget } 关于 GetUsefulFunc 函数传入的字典 { 'SendFunc' = func(Msg) } 关于 AddItem , 调用该方法请传入一个列表和一个str,列表中为要加入list的widget,str为name标签的内容 ''' class PlgFunc: RecvCallBack = 'RecvMethod' GetUsefulFunc = 'GetUsefulFunc' SetupUI = 'SetupUI' DeleteFunc = 'Delete' StartFunc = 'StartFunc' SendCallback = 'SendCallbackFunc' from PyQt5 import QtWidgets, QtCore from PyQt5.QtWidgets import QWidget, QAbstractItemView, QMessageBox, QInputDialog, QLineEdit from PyQt5.QtCore import QStringListModel import time selfName = '' widget = None SendFunc = None AddItem = None ClearFunc = None OnlineUserWidget = None GroupTableWidget = None TabWidget = None widgetList = [] nowGroup = 0 def Init(): print(__name__, '聊天插件初始化成功') callback = { # callback可以理解为插件需要的“权限” PlgFunc.RecvCallBack: RecvFunc, # 接收回调 PlgFunc.GetUsefulFunc: GetFunc, # 获取有用的函数 PlgFunc.SetupUI: SetupUi, # 更新UI,让模块可以在主窗口上创建控件并实现功能 PlgFunc.DeleteFunc: Delete, # 插件被关闭会调用,可以用来保存状态 PlgFunc.StartFunc: Start, PlgFunc.SendCallback: SendCallBack, } return callback def Delete(): # 此处是用于销毁插件创建的控件 for it in widgetList: it.deleteLater() def Start(): Msg = { 'type': 'GetUsers' } # ... def SendCallBack(Msg): # ... def GetFunc(FuncDict): # ... def SetupUi(Widgets): # 创建UI global widget def BtnClick(): # 按钮点击事件 # ... # ... def RecvFunc(Msg): # 接收消息时被调用 # ... return False # 不是自己处理的类型 class CharBox(QWidget): # 聊天框控件 # ... class OnlineUserTable(QWidget): # 侧边栏组件 # ... def GetNickName(): # ... class GroupTable(QWidget): # 侧边栏组件 # ... ``` #### Plugin class详解 初始化: ```python def __init__(self, plugin_dir, plugin_init_args=None): ``` 给定插件存放的目录,以及插件初始化函数,系统会自动获取所有可用的插件,并默认全部不加载,之后从数据库中获取插件启用记录,将需要启用的插件启动。(数据库文件为项目根目录下的`PluginConfig.db`) `list_plugin` 该函数用于列举出所有可使用的插件的名称,即文件夹的名称 `reload_all` 该函数用于重新加载所有插件,即先关闭所有插件,再依次加载需要开启的插件 `SetPluginState` ```python def SetPluginState(self, PluginName, IsUsing=True): ``` 该函数用于启用或关闭插件 `get_plugin_state` 该函数用于获取某个插件的状态(打开还是关闭) `get_plugin_funcs` 该函数是以字典的形式将某个插件的所有回调函数返回,字典是以`{函数名:函数}`的形式。