插件开发
1. 插件基类
ISAT.widgets.plugin_base.py
class PluginBase(ABC):
def __init__(self):
self.enabled = False
@abstractmethod
def init_plugin(self, mainwindow):
"""
接受主程序调用,进行初始化
:param mainwindow: 传入mainwindow,便于访问ISAT主程序的各种方法与属性
"""
pass
@abstractmethod
def enable_plugin(self):
"""
启动插件
:param mainwindow:
:return:
"""
pass
@abstractmethod
def disable_plugin(self):
"""
禁用插件
:param mainwindow:
:return:
"""
pass
@abstractmethod
def get_plugin_author(self) -> str:
"""
获取插件作者
:return:
"""
pass
@abstractmethod
def get_plugin_version(self) -> str:
"""
获取插件版本
:return:
"""
pass
@abstractmethod
def get_plugin_description(self) -> str:
"""
获取插件描述
:return:
"""
pass
def get_plugin_name(self) -> str:
"""
获取插件名
:return:
"""
return self.__class__.__name__
def activate_state_changed(self, checkbox_state):
if checkbox_state:
self.enable_plugin()
else:
self.disable_plugin()
def before_image_open_event(self, image_path: str):
"""
当图片打开前调用
:param image_path: 图片路径
:return:
"""
pass
def after_image_open_event(self):
"""
当图片打开后调用
:param:
:return:
"""
pass
def before_annotation_start_event(self):
"""
当开始标注前调用
:return:
"""
pass
def after_annotation_created_event(self):
"""
当标注创建完成后调用
:return:
"""
pass
def after_annotation_changed_event(self):
"""
当标注发生变化后调用,包括创建新标注,拖动顶点,移动多边形,改变多边形属性等
:return:
"""
pass
def before_annotations_save_event(self):
"""
当保存标注文件前调用
:return:
"""
pass
def after_annotations_saved_event(self):
"""
当保存标注文件后调用
:return:
"""
pass
def after_sam_encode_finished_event(self, index):
"""
当sam编码完成后调用
注意ISAT在单独线程对前后图像进行预编码,通过self.mainwindow.seganythread.results_dict中获取编码结果
:param index: 编码完成的图片index
:return:
"""
pass
def on_mouse_move_event(self, scene_pos):
"""
当鼠标移动时调用
:param scene_pos: 坐标,限制在图像范围内
:return:
"""
pass
def on_mouse_press_event(self, scene_pos):
"""
当鼠标按下时调用
:param scene_pos: 坐标,限制在图像范围内
:return:
"""
pass
def on_mouse_release_event(self, scene_pos):
"""
当鼠标释放时调用
:param scene_pos: 坐标,限制在图像范围内
:return:
"""
pass
def on_mouse_pressed_and_mouse_move_event(self, scene_pos):
"""
当鼠标拖动时调用
:param scene_pos: 坐标,限制在图像范围内
:return:
"""
pass
def application_start_event(self):
"""
软件启动后触发
:return:
"""
pass
def application_shutdown_event(self):
"""
软件关闭前触发
:return:
"""
pass
小技巧
PluginBase 是所有 ISAT 插件的基类
2. 插件入口
setup.py
...
entry_points={
"isat.plugins": []
}
...
重要
所有 ISAT 插件都以 Python 包的形式发布。
插件必须使用 setup.py 将插件类添加到 entry_points 的 isat.plugins 中。
3. 插件获取ISAT数据
从插件基类的事件中获取的数据是有限的。
在开发 ISAT 插件时,可以通过 self.mainwindow 直接访问ISAT数据。
4. 创建你的第一个插件
4.1 插件项目结构
推荐使用下面的文件结构作为插件项目结构。
ProjectName
├── MANIFEST.in
├── requirements.txt
├── README.md
├── setup.py
├── ...
└── PluginPackage
├── __init__.py
├── main.py
└── ...
4.2 编写插件
ProjectName/PluginPackage/__init__.py包含版本,作者,插件描述等信息。
__author__ = "Your name" __version__ = "0.0.1" __description__ = "A short description of the plugin's functionality."
ProjectName/PluginPackage/main.py实现具体的插件类。
from ISAT.widgets.plugin_base import PluginBase class CustomPlugin(PluginBase): def __init__(self): super().__init__() def init_plugin(self, mainwindow): self.mainwindow = mainwindow ... ... # Handle events def after_image_open_event(self): # do something ...
4.3 编写包文件
ProjectName/setup.pyfrom setuptools import setup, find_packages def get_version(): try: from {PluginPackage}.__init__ import __version__ return __version__ except FileExistsError: FileExistsError('__init__.py not exists.') version, author = get_version() setup( name="isat-plugin-{custom}", # It is recommended that the package name start with "isat-plugin". version={version}, author={author}, keywords=["isat-sam", "isat plugin", ...], packages=find_packages(), include_package_data=True, python_requires=">=3.8", install_requires=[ 'isat-sam>=1.4.0', ], entry_points={ "isat.plugins": [ "{custom_plugin} = {PluginPackage}.main:{CustomPlugin}", ] } )
4.4 打包
打包为源码包
cd {ProjectName} python setup.py sdist
安装
pip install dist/{isat_plugin_custom}-{version}.tar.gz
小技巧
你可以参考插件:AutoAnnotatePlugin and MaskExportPlugin 开发自己的插件。