1818if TYPE_CHECKING :
1919 from PyQt5 .QtGui import QIcon
2020
21- from PyQt5 .QtCore import Qt
21+ from PyQt5 .QtCore import Qt , QObject
2222from PyQt5 .QtGui import QIcon , QPixmap , QPainter , QPen , QColor , QBrush , QFont
2323
2424from lib_zmq_plugins .shared .base import BaseEvent , get_event_tag
@@ -169,31 +169,41 @@ def __init__(self, info: PluginInfo):
169169 log_config = info .log_config , # 插件可自定义轮转策略
170170 )
171171 self ._log_level : LogLevel = info .log_level # 当前日志级别
172-
172+
173173 # ═══════════════════════════════════════════════════════════════════
174174 # 属性
175175 # ═══════════════════════════════════════════════════════════════════
176-
176+
177177 @property
178178 def info (self ) -> PluginInfo :
179179 return self ._info
180-
180+
181181 @property
182182 def name (self ) -> str :
183183 return self ._info .name
184-
184+
185185 @property
186186 def is_enabled (self ) -> bool :
187187 return self ._info .enabled
188-
188+
189189 @property
190190 def widget (self ) -> QWidget | None :
191191 return self ._widget
192-
192+
193193 @property
194194 def client (self ) -> ZMQClient | None :
195195 return self ._client
196196
197+ @property
198+ def data_dir (self ) -> "Path" :
199+ """插件专属数据目录(可写),自动根据插件类名创建"""
200+ from pathlib import Path
201+ from .app_paths import get_plugin_data_dir
202+
203+ if not hasattr (self , "_data_dir" ):
204+ self ._data_dir = get_plugin_data_dir (type (self ))
205+ return self ._data_dir
206+
197207 @property
198208 def log_level (self ) -> LogLevel :
199209 """当前日志级别"""
@@ -211,55 +221,55 @@ def set_log_level(self, level: LogLevel | str) -> None:
211221 level = LogLevel (level .upper ())
212222 self ._log_level = level
213223 set_plugin_log_level (self ._log_sink_id , level )
214- self .logger .debug ("Log level changed to %s" , level )
224+ self .logger .debug (f "Log level changed to { level } " )
215225
216226 @property
217227 def plugin_icon (self ) -> QIcon :
218228 """返回插件图标(使用 PluginInfo.icon,未设置则生成默认图标)"""
219229 if self ._info .icon :
220230 return self ._info .icon
221231 return make_plugin_icon ()
222-
232+
223233 # ═══════════════════════════════════════════════════════════════════
224234 # 生命周期
225235 # ═══════════════════════════════════════════════════════════════════
226-
236+
227237 def set_client (self , client : ZMQClient ) -> None :
228238 self ._client = client
229-
239+
230240 def set_event_dispatcher (self , dispatcher : EventDispatcher ) -> None :
231241 self ._event_dispatcher = dispatcher
232-
242+
233243 def initialize (self ) -> None :
234244 """初始化插件"""
235245 if self ._initialized :
236246 return
237-
247+
238248 self ._setup_subscriptions ()
239249 self ._widget = self ._create_widget ()
240250 self ._initialized = True
241251 self .on_initialized ()
242-
252+
243253 def shutdown (self ) -> None :
244254 """关闭插件"""
245255 if not self ._initialized :
246256 return
247-
257+
248258 self .on_shutdown ()
249-
259+
250260 if self ._event_dispatcher :
251261 self ._event_dispatcher .unsubscribe_all (self )
252-
262+
253263 if self ._widget :
254264 self ._widget .deleteLater ()
255265 self ._widget = None
256-
266+
257267 self ._initialized = False
258-
268+
259269 # ═══════════════════════════════════════════════════════════════════
260270 # 抽象方法
261271 # ═══════════════════════════════════════════════════════════════════
262-
272+
263273 @abstractmethod
264274 def _setup_subscriptions (self ) -> None :
265275 """
@@ -270,27 +280,27 @@ def _setup_subscriptions(self) -> None:
270280 self.subscribe(BoardUpdateEvent, self._on_board_update)
271281 """
272282 pass
273-
283+
274284 # ═══════════════════════════════════════════════════════════════════
275285 # 可选重写
276286 # ═══════════════════════════════════════════════════════════════════
277-
287+
278288 def _create_widget (self ) -> QWidget | None :
279289 """创建界面组件,返回 None 表示无界面"""
280290 return None
281-
291+
282292 def on_initialized (self ) -> None :
283293 """插件初始化完成回调"""
284294 pass
285-
295+
286296 def on_shutdown (self ) -> None :
287297 """插件关闭前回调"""
288298 pass
289-
299+
290300 # ═══════════════════════════════════════════════════════════════════
291301 # 事件订阅(使用事件类)
292302 # ═══════════════════════════════════════════════════════════════════
293-
303+
294304 def subscribe (
295305 self ,
296306 event_class : type [_E ],
@@ -306,43 +316,43 @@ def subscribe(
306316 if self ._event_dispatcher :
307317 tag = get_event_tag (event_class )
308318 self ._event_dispatcher .subscribe (tag , handler , self ._info .priority , self )
309-
319+
310320 def unsubscribe (self , event_class : type [BaseEvent ]) -> None :
311321 """取消订阅事件"""
312322 if self ._event_dispatcher :
313323 tag = get_event_tag (event_class )
314324 self ._event_dispatcher .unsubscribe (tag , self )
315-
325+
316326 # ═══════════════════════════════════════════════════════════════════
317327 # 指令发送
318328 # ═══════════════════════════════════════════════════════════════════
319-
329+
320330 def send_command (self , command : Any ) -> None :
321331 """发送控制指令到主进程(异步)"""
322332 if self ._client :
323333 self ._client .send_command (command )
324-
334+
325335 def request (self , command : Any , timeout : float = 5.0 ) -> Any :
326336 """发送请求并等待响应(同步)"""
327337 if self ._client :
328338 return self ._client .request (command , timeout )
329339 return None
330-
340+
331341 # ═══════════════════════════════════════════════════════════════════
332342 # 辅助
333343 # ═══════════════════════════════════════════════════════════════════
334-
344+
335345 def enable (self ) -> None :
336346 """启用插件"""
337347 self ._info .enabled = True
338348 if not self ._initialized :
339349 self .initialize ()
340-
350+
341351 def disable (self ) -> None :
342352 """禁用插件"""
343353 self ._info .enabled = False
344354 if self ._initialized :
345355 self .shutdown ()
346-
356+
347357 def __repr__ (self ) -> str :
348358 return f"<Plugin { self ._info .name } v{ self ._info .version } >"
0 commit comments