import os import time import logging import threading from .plugin_registry import Event from PySide6.QtWidgets import QFrame from PySide6.QtCore import Signal from .plugins_card_ui import Ui_FramePluginsCard logger = logging.getLogger(__name__) def parse_version(version: str) -> tuple: """将版本字符串解析为可比较的元组,如 '1.10.0' -> (1, 10, 0)。 非数字段保持原样(字符串与整数混排时按元组规则比较,足够覆盖 常见的 '1.0.0' / '1.10.3' 场景)。None/空值/解析失败返回 (0,), 视为最低版本。 """ if not version: return (0,) try: parts = [] for seg in str(version).split('.'): seg = seg.strip() if seg.isdigit(): parts.append(int(seg)) else: parts.append(seg) return tuple(parts) if parts else (0,) except Exception: return (0,) class PluginsCard(QFrame, Ui_FramePluginsCard): """工具卡片类 继承自 QFrame(Qt 帧基类)和 Ui_FrameToolCard(Qt Designer 生成的 UI 界面) 负责显示工具的卡片界面,包含工具的图标、名称和描述。 """ send_event_signal = Signal(Event,str) def __init__(self, name: str, info:dict, parent=None) -> None: super().__init__(parent) self.setupUi(self) self.name = name self.info = info self.initUI() def initUI(self): self.refresh() self.textBrowser.setReadOnly(True) self.pushButtonUpdate.clicked.connect(self.on_update_event) self.pushButtonInstall.clicked.connect(self.on_install_event) self.pushButtonUninstall.clicked.connect(self.on_uninstall_event) def refresh(self) -> None: """根据 info 刷新卡片显示与按钮状态。""" self.textBrowser.setMarkdown(self.to_card()) installed = self.info.get("local version") is not None self.pushButtonInstall.setEnabled(not installed) self.pushButtonUninstall.setEnabled(installed) if installed: remote = parse_version(self.info.get('remote version')) local = parse_version(self.info.get('local version')) self.pushButtonUpdate.setEnabled(remote > local) else: self.pushButtonUpdate.setEnabled(False) def to_card(self): remote_ver = self.info.get('remote version') local_ver = self.info.get('local version') desc = self.info.get('remote description') or self.info.get('local description') or '暂无' card = f"# {self.name}\n\n" card += f"**最新:** V{remote_ver}\n\n" if remote_ver else f"**最新:** 暂无版本信息\n\n" if local_ver is None: card += f"**当前:** 未安装!\n\n" else: card += f"**当前:** V{local_ver}\n\n" card += f"**描述:** {desc}" return card def on_install_event(self): self.send_event_signal.emit(Event.Install, self.name) def on_uninstall_event(self): self.send_event_signal.emit(Event.Uninstall, self.name) def on_update_event(self): self.send_event_signal.emit(Event.Update, self.name)