优化
This commit is contained in:
+3
-2
@@ -12,7 +12,8 @@ Version: 0.0.1
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from .logging.log import FrameLog
|
from .logging.log import FrameLog
|
||||||
from .tools.tools import ToolsWindow # FromTools → ToolsWindow
|
from .plugin.plugins import Plugins
|
||||||
|
from .plugin.plugin_registry import PluginRegistry
|
||||||
|
|
||||||
__all__ = ["FrameLog", "ToolsWindow"]
|
__all__ = ["FrameLog", "ToolsWindow","PluginRegistry"]
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,127 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import logging
|
||||||
|
import importlib
|
||||||
|
import threading
|
||||||
|
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from enum import Enum, auto
|
||||||
|
from PySide6.QtCore import QObject,Signal
|
||||||
|
from dataclasses import dataclass, field, fields
|
||||||
|
|
||||||
|
LOCAL_PLUGINS_PATH = Path("./plugins")
|
||||||
|
REMOTE_PLUGINS_PATH = Path('Y:/SE/xufeifei/plugins')
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Event(Enum):
|
||||||
|
Update = auto()
|
||||||
|
Install = auto()
|
||||||
|
Uninstall = auto()
|
||||||
|
|
||||||
|
class PluginRegistry(QObject):
|
||||||
|
"""插件注册中心。"""
|
||||||
|
plugins_loader_signal = Signal(dict)
|
||||||
|
update_plugins_card_signal = Signal(dict)
|
||||||
|
def __init__(self, parent = None) -> None:
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
self.plugins = dict()
|
||||||
|
|
||||||
|
self.start_discover_local(LOCAL_PLUGINS_PATH, self.plugins)
|
||||||
|
self.start_discover_remote(REMOTE_PLUGINS_PATH, self.plugins)
|
||||||
|
|
||||||
|
def start_discover_local(self,plugins_dir: Path, plugins:dict):
|
||||||
|
self.thread_local = threading.Thread(target= self.discover_local_event,args=(plugins_dir, plugins,))
|
||||||
|
self.thread_local.start()
|
||||||
|
|
||||||
|
def discover_local_event(self, plugins_dir: Path, plugins:dict):
|
||||||
|
if not os.path.exists(plugins_dir):
|
||||||
|
os.mkdir(plugins_dir)
|
||||||
|
return
|
||||||
|
|
||||||
|
sys.path.append(str(plugins_dir))
|
||||||
|
for tool in Path(plugins_dir).glob("*.pyd"):
|
||||||
|
tool_name = tool.stem
|
||||||
|
try:
|
||||||
|
module = importlib.import_module(tool_name)
|
||||||
|
obj = module.create_plugin()
|
||||||
|
name = module.read_plugin_name()
|
||||||
|
version = module.read_plugin_version()
|
||||||
|
if name in plugins.keys():
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
plugins[name] = {}
|
||||||
|
plugins[name]['obj'] = obj
|
||||||
|
plugins[name]['local version'] = version
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"插件{tool_name}注册失败,{str(e)}")
|
||||||
|
sys.path.remove(str(LOCAL_PLUGINS_PATH))
|
||||||
|
self.plugins_loader_signal.emit(plugins)
|
||||||
|
|
||||||
|
|
||||||
|
def start_discover_remote(self,plugins_dir: Path, plugins:dict):
|
||||||
|
self.thread_remote = threading.Thread(target= self.discover_remote_event,args=(plugins_dir, plugins,))
|
||||||
|
self.thread_remote.start()
|
||||||
|
|
||||||
|
def discover_remote_event(self, plugins_dir: Path, plugins:dict):
|
||||||
|
if not os.path.exists(plugins_dir):
|
||||||
|
logger.error("服务器链接错误!")
|
||||||
|
return
|
||||||
|
#读取服务器工具信息
|
||||||
|
time.sleep(0.01)
|
||||||
|
sys.path.append(str(plugins_dir))
|
||||||
|
for tool in Path(plugins_dir).glob("*.pyd"):
|
||||||
|
tool_name = tool.stem
|
||||||
|
try:
|
||||||
|
module = importlib.import_module(tool_name)
|
||||||
|
|
||||||
|
name = module.read_plugin_name()
|
||||||
|
version = module.read_plugin_version()
|
||||||
|
description = module.read_plugin_description()
|
||||||
|
if name in plugins.keys():
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print("discover_remote_event")
|
||||||
|
plugins[name] = {}
|
||||||
|
plugins[name]["tool_name"] = tool_name
|
||||||
|
plugins[name]["local version"] = None
|
||||||
|
plugins[name]["local description"] = None
|
||||||
|
plugins[name]["remote version"] = version
|
||||||
|
plugins[name]["remote description"] = description
|
||||||
|
plugins[name]['remote path'] = plugins_dir
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"服务器{tool_name}无法加载:{str(e)}")
|
||||||
|
sys.path.remove(str(plugins_dir))
|
||||||
|
self.update_plugins_card_signal.emit(plugins)
|
||||||
|
|
||||||
|
def start_plugins_event(self, event:Event, name:str):
|
||||||
|
if event == Event.Install:
|
||||||
|
local_path = str(LOCAL_PLUGINS_PATH) + '\\' + f"{self.plugins[name]['tool_name']}.pyd"
|
||||||
|
remote_path = str(REMOTE_PLUGINS_PATH) + '\\' + f"{self.plugins[name]['tool_name']}.pyd"
|
||||||
|
|
||||||
|
self.sub_thread = threading.Thread(target= self.install_plugins_event,args=(local_path,remote_path,))
|
||||||
|
self.sub_thread.start()
|
||||||
|
pass
|
||||||
|
|
||||||
|
def install_plugins_event(self, local_path, remote_path):
|
||||||
|
try:
|
||||||
|
total_size = os.path.getsize(remote_path)
|
||||||
|
copied_size = 0
|
||||||
|
|
||||||
|
with open(remote_path, 'rb') as fsrc, open(local_path, 'wb') as fdst:
|
||||||
|
while True:
|
||||||
|
buf = fsrc.read(1024*1024)
|
||||||
|
if not buf:
|
||||||
|
break
|
||||||
|
fdst.write(buf)
|
||||||
|
copied_size += len(buf)
|
||||||
|
logger.info(f"安装进度: {copied_size/1024/1024:.2f} MB / {total_size/1024/1024:.2f} MB")
|
||||||
|
time.sleep(0.1)
|
||||||
|
logger.info(f"{local_path}安装成功!!!")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"{remote_path}安装失败{e.args}")
|
||||||
|
return
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
"""
|
||||||
|
工具箱模块
|
||||||
|
|
||||||
|
提供工具箱主窗口,包含各种实用工具的入口。
|
||||||
|
使用 PySide6 构建的窗口框架。
|
||||||
|
|
||||||
|
主要功能:
|
||||||
|
- 工具箱主窗口界面
|
||||||
|
- 窗口居中显示功能
|
||||||
|
- 工具分类和导航
|
||||||
|
|
||||||
|
Author: Model Team
|
||||||
|
Version: 0.0.1
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
import threading
|
||||||
|
import importlib
|
||||||
|
|
||||||
|
from qt_material import apply_stylesheet
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from .plugins_ui import Ui_FormPlugins
|
||||||
|
from PySide6.QtGui import QIcon
|
||||||
|
|
||||||
|
from PySide6.QtWidgets import QWidget, QListWidgetItem
|
||||||
|
from PySide6.QtCore import QSize,Signal
|
||||||
|
|
||||||
|
from .plugins_card import PluginsCard
|
||||||
|
from .plugin_registry import PluginRegistry
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
LOCAL_PLUGINS_PATH = Path("./plugins")
|
||||||
|
REMOTE_PLUGINS_PATH = Path('Y:/SE/xufeifei/plugins')
|
||||||
|
|
||||||
|
class Plugins(QWidget, Ui_FormPlugins):
|
||||||
|
"""工具箱主窗口类
|
||||||
|
|
||||||
|
继承自 QWidget(Qt 窗口基类)和 Ui_FormTools(Qt Designer 生成的 UI 界面)
|
||||||
|
负责显示工具箱的主界面,提供工具的分类和导航功能。
|
||||||
|
|
||||||
|
窗口特性:
|
||||||
|
- 默认尺寸: 400x293 像素
|
||||||
|
- 支持窗口居中显示
|
||||||
|
- 可作为独立窗口或嵌入其他窗口使用
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
parent: 父窗口对象,默认为 None(顶级窗口)
|
||||||
|
"""
|
||||||
|
update_tool_card = Signal(dict)
|
||||||
|
|
||||||
|
def __init__(self, plugin_registry:PluginRegistry, parent: QWidget = None) -> None:
|
||||||
|
"""初始化工具箱窗口
|
||||||
|
|
||||||
|
创建工具箱窗口实例,初始化 UI 界面。
|
||||||
|
|
||||||
|
Args:
|
||||||
|
parent: 父窗口对象,用于建立父子关系。
|
||||||
|
默认为 None,表示这是顶级窗口。
|
||||||
|
"""
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setupUi(self)
|
||||||
|
|
||||||
|
self.plugin_registry = plugin_registry
|
||||||
|
|
||||||
|
self.initUI()
|
||||||
|
self.load_stylesheet()
|
||||||
|
self.plugin_registry.update_plugins_card_signal.connect(self.on_update_plugins_card)
|
||||||
|
|
||||||
|
def initUI(self) -> None:
|
||||||
|
"""
|
||||||
|
初始化用户界面
|
||||||
|
|
||||||
|
配置窗口标题、图标、大小和居中显示。
|
||||||
|
"""
|
||||||
|
self.setWindowTitle("工具箱")
|
||||||
|
self.setWindowIcon(QIcon('resources/tools.ico'))
|
||||||
|
|
||||||
|
# self.update_tool_card.connect(self.on_update_tool_card)
|
||||||
|
|
||||||
|
def load_stylesheet(self) -> None:
|
||||||
|
"""
|
||||||
|
加载 Qt 样式表和自定义样式文件
|
||||||
|
|
||||||
|
使用 qt_material 库加载暗色主题,并应用自定义 QSS 样式表
|
||||||
|
失败时记录错误日志,但不影响应用继续运行(降级策略)
|
||||||
|
|
||||||
|
异常处理:
|
||||||
|
- FileNotFoundError: 样式文件不存在
|
||||||
|
- RuntimeError: 主题加载失败
|
||||||
|
- 其他异常: 记录警告但不中断应用
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
apply_stylesheet(self, style=None,theme='dark_teal.xml', css_file='resources/my.qss')
|
||||||
|
except FileNotFoundError as e:
|
||||||
|
logger.warning(f"样式文件未找到,使用默认主题: {e}")
|
||||||
|
except RuntimeError as e:
|
||||||
|
logger.warning(f"主题加载失败,使用默认主题: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"样式加载失败,使用默认主题: {e}")
|
||||||
|
|
||||||
|
# def start_load_tools(self):
|
||||||
|
# self.sub_thread = threading.Thread(target= self.load_tool_list,args=(self.tools,))
|
||||||
|
# self.sub_thread.start()
|
||||||
|
|
||||||
|
# def load_tool_list(self, tools:dict):
|
||||||
|
# if not os.path.exists(REMOTE_PLUGINS_PATH):
|
||||||
|
# logger.error("服务器链接错误!")
|
||||||
|
# return
|
||||||
|
# #读取服务器工具信息
|
||||||
|
# sys.path.append(str(REMOTE_PLUGINS_PATH))
|
||||||
|
# for tool in Path(REMOTE_PLUGINS_PATH).glob("*.pyd"):
|
||||||
|
# tool_name = tool.stem
|
||||||
|
# try:
|
||||||
|
# module = importlib.import_module(tool_name)
|
||||||
|
|
||||||
|
# name = module.read_tool_name()
|
||||||
|
# version = module.read_tool_version()
|
||||||
|
# description = module.read_tool_description()
|
||||||
|
# if name in tools.keys():
|
||||||
|
# pass
|
||||||
|
# else:
|
||||||
|
# tools[name] = {}
|
||||||
|
# tools[name]["name"] = tool_name
|
||||||
|
# tools[name]["local version"] = None
|
||||||
|
# tools[name]["local description"] = None
|
||||||
|
# tools[name]["remote version"] = version
|
||||||
|
# tools[name]["remote description"] = description
|
||||||
|
# tools[name]['remote path'] = REMOTE_PLUGINS_PATH
|
||||||
|
# except Exception as e:
|
||||||
|
# logger.error(f"服务器{tool_name}无法加载:{str(e)}")
|
||||||
|
# sys.path.remove(str(REMOTE_PLUGINS_PATH))
|
||||||
|
# self.update_tool_card.emit(tools)
|
||||||
|
|
||||||
|
def on_update_plugins_card(self, plugins:dict):
|
||||||
|
# print(plugins)
|
||||||
|
for name in plugins.keys():
|
||||||
|
item = QListWidgetItem(self.listWidget)
|
||||||
|
plugin_card = PluginsCard(name, plugins[name])
|
||||||
|
plugin_card.send_event_signal.connect(self.plugin_registry.start_plugins_event)
|
||||||
|
|
||||||
|
|
||||||
|
item.setSizeHint(QSize(plugin_card.sizeHint().width(), 200))
|
||||||
|
self.listWidget.addItem(item)
|
||||||
|
self.listWidget.setCurrentItem(item)
|
||||||
|
self.listWidget.setItemWidget(item, plugin_card)
|
||||||
|
pass
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>FormTools</class>
|
<class>FormPlugins</class>
|
||||||
<widget class="QWidget" name="FormTools">
|
<widget class="QWidget" name="FormPlugins">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
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__)
|
||||||
|
|
||||||
|
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.textBrowser.setReadOnly(True)
|
||||||
|
self.textBrowser.setMarkdown(self.to_card())
|
||||||
|
if self.info["local version"] is None:
|
||||||
|
self.pushButtonUpdate.setEnabled(False)
|
||||||
|
self.pushButtonUninstall.setEnabled(False)
|
||||||
|
else:
|
||||||
|
self.pushButtonInstall.setEnabled(False)
|
||||||
|
if self.info['remote version'] <= self.info['local version']:
|
||||||
|
self.pushButtonUpdate.setEnabled(False)
|
||||||
|
self.pushButtonInstall.clicked.connect(self.on_intsall_event)
|
||||||
|
|
||||||
|
def to_card(self):
|
||||||
|
card = f"# {self.name}\n\n"
|
||||||
|
card += f"**最新:** V{self.info['remote version']}\n\n"
|
||||||
|
if self.info['local version'] is None:
|
||||||
|
card += f"**当前:** 未安装!\n\n"
|
||||||
|
else:
|
||||||
|
card += f"**当前:** V{self.info['local version']}\n\n"
|
||||||
|
card += f"**描述:** {self.info['remote description']}"
|
||||||
|
return card
|
||||||
|
|
||||||
|
def on_intsall_event(self):
|
||||||
|
self.send_event_signal.emit(Event.Install, self.name)
|
||||||
@@ -1,48 +1,34 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>FrameToolCard</class>
|
<class>FramePluginsCard</class>
|
||||||
<widget class="QFrame" name="FrameToolCard">
|
<widget class="QFrame" name="FramePluginsCard">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>491</width>
|
<width>357</width>
|
||||||
<height>64</height>
|
<height>120</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Frame</string>
|
<string>Frame</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<widget class="QTextBrowser" name="textBrowser"/>
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="labelName">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Name</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QPushButton" name="pushButtonInstall">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<property name="sizePolicy">
|
<item row="2" column="0">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>安装</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QPushButton" name="pushButtonUninstall">
|
<widget class="QPushButton" name="pushButtonUninstall">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
@@ -55,7 +41,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="3">
|
<item row="3" column="0">
|
||||||
<widget class="QPushButton" name="pushButtonUpdate">
|
<widget class="QPushButton" name="pushButtonUpdate">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
@@ -68,21 +54,34 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="labelInfo">
|
<widget class="QPushButton" name="pushButtonInstall">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TextLabel</string>
|
<string>安装</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
## Form generated from reading UI file 'plugins_card.ui'
|
||||||
|
##
|
||||||
|
## Created by: Qt User Interface Compiler version 6.11.1
|
||||||
|
##
|
||||||
|
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||||
|
QMetaObject, QObject, QPoint, QRect,
|
||||||
|
QSize, QTime, QUrl, Qt)
|
||||||
|
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||||
|
QFont, QFontDatabase, QGradient, QIcon,
|
||||||
|
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||||
|
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||||
|
from PySide6.QtWidgets import (QApplication, QFrame, QGridLayout, QPushButton,
|
||||||
|
QSizePolicy, QSpacerItem, QTextBrowser, QWidget)
|
||||||
|
|
||||||
|
class Ui_FramePluginsCard(object):
|
||||||
|
def setupUi(self, FramePluginsCard):
|
||||||
|
if not FramePluginsCard.objectName():
|
||||||
|
FramePluginsCard.setObjectName(u"FramePluginsCard")
|
||||||
|
FramePluginsCard.resize(357, 120)
|
||||||
|
sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(FramePluginsCard.sizePolicy().hasHeightForWidth())
|
||||||
|
FramePluginsCard.setSizePolicy(sizePolicy)
|
||||||
|
FramePluginsCard.setAutoFillBackground(True)
|
||||||
|
self.gridLayout_2 = QGridLayout(FramePluginsCard)
|
||||||
|
self.gridLayout_2.setObjectName(u"gridLayout_2")
|
||||||
|
self.textBrowser = QTextBrowser(FramePluginsCard)
|
||||||
|
self.textBrowser.setObjectName(u"textBrowser")
|
||||||
|
|
||||||
|
self.gridLayout_2.addWidget(self.textBrowser, 0, 0, 1, 1)
|
||||||
|
|
||||||
|
self.gridLayout = QGridLayout()
|
||||||
|
self.gridLayout.setObjectName(u"gridLayout")
|
||||||
|
self.pushButtonUninstall = QPushButton(FramePluginsCard)
|
||||||
|
self.pushButtonUninstall.setObjectName(u"pushButtonUninstall")
|
||||||
|
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
||||||
|
sizePolicy1.setHorizontalStretch(0)
|
||||||
|
sizePolicy1.setVerticalStretch(0)
|
||||||
|
sizePolicy1.setHeightForWidth(self.pushButtonUninstall.sizePolicy().hasHeightForWidth())
|
||||||
|
self.pushButtonUninstall.setSizePolicy(sizePolicy1)
|
||||||
|
|
||||||
|
self.gridLayout.addWidget(self.pushButtonUninstall, 2, 0, 1, 1)
|
||||||
|
|
||||||
|
self.pushButtonUpdate = QPushButton(FramePluginsCard)
|
||||||
|
self.pushButtonUpdate.setObjectName(u"pushButtonUpdate")
|
||||||
|
sizePolicy1.setHeightForWidth(self.pushButtonUpdate.sizePolicy().hasHeightForWidth())
|
||||||
|
self.pushButtonUpdate.setSizePolicy(sizePolicy1)
|
||||||
|
|
||||||
|
self.gridLayout.addWidget(self.pushButtonUpdate, 3, 0, 1, 1)
|
||||||
|
|
||||||
|
self.pushButtonInstall = QPushButton(FramePluginsCard)
|
||||||
|
self.pushButtonInstall.setObjectName(u"pushButtonInstall")
|
||||||
|
sizePolicy1.setHeightForWidth(self.pushButtonInstall.sizePolicy().hasHeightForWidth())
|
||||||
|
self.pushButtonInstall.setSizePolicy(sizePolicy1)
|
||||||
|
|
||||||
|
self.gridLayout.addWidget(self.pushButtonInstall, 1, 0, 1, 1)
|
||||||
|
|
||||||
|
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
|
||||||
|
|
||||||
|
self.gridLayout.addItem(self.verticalSpacer, 0, 0, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
|
self.gridLayout_2.addLayout(self.gridLayout, 0, 1, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
|
self.retranslateUi(FramePluginsCard)
|
||||||
|
|
||||||
|
QMetaObject.connectSlotsByName(FramePluginsCard)
|
||||||
|
# setupUi
|
||||||
|
|
||||||
|
def retranslateUi(self, FramePluginsCard):
|
||||||
|
FramePluginsCard.setWindowTitle(QCoreApplication.translate("FramePluginsCard", u"Frame", None))
|
||||||
|
self.pushButtonUninstall.setText(QCoreApplication.translate("FramePluginsCard", u"\u5378\u8f7d", None))
|
||||||
|
self.pushButtonUpdate.setText(QCoreApplication.translate("FramePluginsCard", u"\u66f4\u65b0", None))
|
||||||
|
self.pushButtonInstall.setText(QCoreApplication.translate("FramePluginsCard", u"\u5b89\u88c5", None))
|
||||||
|
# retranslateUi
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
## Form generated from reading UI file 'tools.ui'
|
## Form generated from reading UI file 'plugins.ui'
|
||||||
##
|
##
|
||||||
## Created by: Qt User Interface Compiler version 6.11.1
|
## Created by: Qt User Interface Compiler version 6.11.1
|
||||||
##
|
##
|
||||||
@@ -18,30 +18,30 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
|||||||
from PySide6.QtWidgets import (QApplication, QGridLayout, QListWidget, QListWidgetItem,
|
from PySide6.QtWidgets import (QApplication, QGridLayout, QListWidget, QListWidgetItem,
|
||||||
QSizePolicy, QWidget)
|
QSizePolicy, QWidget)
|
||||||
|
|
||||||
class Ui_FormTools(object):
|
class Ui_FormPlugins(object):
|
||||||
def setupUi(self, FormTools):
|
def setupUi(self, FormPlugins):
|
||||||
if not FormTools.objectName():
|
if not FormPlugins.objectName():
|
||||||
FormTools.setObjectName(u"FormTools")
|
FormPlugins.setObjectName(u"FormPlugins")
|
||||||
FormTools.resize(810, 423)
|
FormPlugins.resize(810, 423)
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||||
sizePolicy.setHorizontalStretch(0)
|
sizePolicy.setHorizontalStretch(0)
|
||||||
sizePolicy.setVerticalStretch(0)
|
sizePolicy.setVerticalStretch(0)
|
||||||
sizePolicy.setHeightForWidth(FormTools.sizePolicy().hasHeightForWidth())
|
sizePolicy.setHeightForWidth(FormPlugins.sizePolicy().hasHeightForWidth())
|
||||||
FormTools.setSizePolicy(sizePolicy)
|
FormPlugins.setSizePolicy(sizePolicy)
|
||||||
self.gridLayout = QGridLayout(FormTools)
|
self.gridLayout = QGridLayout(FormPlugins)
|
||||||
self.gridLayout.setObjectName(u"gridLayout")
|
self.gridLayout.setObjectName(u"gridLayout")
|
||||||
self.listWidget = QListWidget(FormTools)
|
self.listWidget = QListWidget(FormPlugins)
|
||||||
self.listWidget.setObjectName(u"listWidget")
|
self.listWidget.setObjectName(u"listWidget")
|
||||||
|
|
||||||
self.gridLayout.addWidget(self.listWidget, 0, 0, 1, 1)
|
self.gridLayout.addWidget(self.listWidget, 0, 0, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
self.retranslateUi(FormTools)
|
self.retranslateUi(FormPlugins)
|
||||||
|
|
||||||
QMetaObject.connectSlotsByName(FormTools)
|
QMetaObject.connectSlotsByName(FormPlugins)
|
||||||
# setupUi
|
# setupUi
|
||||||
|
|
||||||
def retranslateUi(self, FormTools):
|
def retranslateUi(self, FormPlugins):
|
||||||
FormTools.setWindowTitle(QCoreApplication.translate("FormTools", u"Form", None))
|
FormPlugins.setWindowTitle(QCoreApplication.translate("FormPlugins", u"Form", None))
|
||||||
# retranslateUi
|
# retranslateUi
|
||||||
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
|
|
||||||
from PySide6.QtWidgets import QFrame
|
|
||||||
from .tool_card_ui import Ui_FrameToolCard
|
|
||||||
|
|
||||||
|
|
||||||
class ToolCard(QFrame, Ui_FrameToolCard):
|
|
||||||
"""工具卡片类
|
|
||||||
|
|
||||||
继承自 QFrame(Qt 帧基类)和 Ui_FrameToolCard(Qt Designer 生成的 UI 界面)
|
|
||||||
负责显示工具的卡片界面,包含工具的图标、名称和描述。
|
|
||||||
"""
|
|
||||||
def __init__(self, parent = None) -> None:
|
|
||||||
super().__init__(parent)
|
|
||||||
self.setupUi(self)
|
|
||||||
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
## Form generated from reading UI file 'tool_card.ui'
|
|
||||||
##
|
|
||||||
## Created by: Qt User Interface Compiler version 6.11.1
|
|
||||||
##
|
|
||||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
|
||||||
QMetaObject, QObject, QPoint, QRect,
|
|
||||||
QSize, QTime, QUrl, Qt)
|
|
||||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
|
||||||
QFont, QFontDatabase, QGradient, QIcon,
|
|
||||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
|
||||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
|
||||||
from PySide6.QtWidgets import (QApplication, QFrame, QGridLayout, QLabel,
|
|
||||||
QPushButton, QSizePolicy, QWidget)
|
|
||||||
|
|
||||||
class Ui_FrameToolCard(object):
|
|
||||||
def setupUi(self, FrameToolCard):
|
|
||||||
if not FrameToolCard.objectName():
|
|
||||||
FrameToolCard.setObjectName(u"FrameToolCard")
|
|
||||||
FrameToolCard.resize(491, 64)
|
|
||||||
self.gridLayout_2 = QGridLayout(FrameToolCard)
|
|
||||||
self.gridLayout_2.setObjectName(u"gridLayout_2")
|
|
||||||
self.gridLayout = QGridLayout()
|
|
||||||
self.gridLayout.setObjectName(u"gridLayout")
|
|
||||||
self.labelName = QLabel(FrameToolCard)
|
|
||||||
self.labelName.setObjectName(u"labelName")
|
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.labelName.sizePolicy().hasHeightForWidth())
|
|
||||||
self.labelName.setSizePolicy(sizePolicy)
|
|
||||||
|
|
||||||
self.gridLayout.addWidget(self.labelName, 0, 0, 1, 1)
|
|
||||||
|
|
||||||
self.pushButtonInstall = QPushButton(FrameToolCard)
|
|
||||||
self.pushButtonInstall.setObjectName(u"pushButtonInstall")
|
|
||||||
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
|
||||||
sizePolicy1.setHorizontalStretch(0)
|
|
||||||
sizePolicy1.setVerticalStretch(0)
|
|
||||||
sizePolicy1.setHeightForWidth(self.pushButtonInstall.sizePolicy().hasHeightForWidth())
|
|
||||||
self.pushButtonInstall.setSizePolicy(sizePolicy1)
|
|
||||||
|
|
||||||
self.gridLayout.addWidget(self.pushButtonInstall, 0, 1, 1, 1)
|
|
||||||
|
|
||||||
self.pushButtonUninstall = QPushButton(FrameToolCard)
|
|
||||||
self.pushButtonUninstall.setObjectName(u"pushButtonUninstall")
|
|
||||||
sizePolicy1.setHeightForWidth(self.pushButtonUninstall.sizePolicy().hasHeightForWidth())
|
|
||||||
self.pushButtonUninstall.setSizePolicy(sizePolicy1)
|
|
||||||
|
|
||||||
self.gridLayout.addWidget(self.pushButtonUninstall, 0, 2, 1, 1)
|
|
||||||
|
|
||||||
self.pushButtonUpdate = QPushButton(FrameToolCard)
|
|
||||||
self.pushButtonUpdate.setObjectName(u"pushButtonUpdate")
|
|
||||||
sizePolicy1.setHeightForWidth(self.pushButtonUpdate.sizePolicy().hasHeightForWidth())
|
|
||||||
self.pushButtonUpdate.setSizePolicy(sizePolicy1)
|
|
||||||
|
|
||||||
self.gridLayout.addWidget(self.pushButtonUpdate, 0, 3, 1, 1)
|
|
||||||
|
|
||||||
|
|
||||||
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
|
|
||||||
|
|
||||||
self.labelInfo = QLabel(FrameToolCard)
|
|
||||||
self.labelInfo.setObjectName(u"labelInfo")
|
|
||||||
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Expanding)
|
|
||||||
sizePolicy2.setHorizontalStretch(0)
|
|
||||||
sizePolicy2.setVerticalStretch(0)
|
|
||||||
sizePolicy2.setHeightForWidth(self.labelInfo.sizePolicy().hasHeightForWidth())
|
|
||||||
self.labelInfo.setSizePolicy(sizePolicy2)
|
|
||||||
|
|
||||||
self.gridLayout_2.addWidget(self.labelInfo, 1, 0, 1, 1)
|
|
||||||
|
|
||||||
|
|
||||||
self.retranslateUi(FrameToolCard)
|
|
||||||
|
|
||||||
QMetaObject.connectSlotsByName(FrameToolCard)
|
|
||||||
# setupUi
|
|
||||||
|
|
||||||
def retranslateUi(self, FrameToolCard):
|
|
||||||
FrameToolCard.setWindowTitle(QCoreApplication.translate("FrameToolCard", u"Frame", None))
|
|
||||||
self.labelName.setText(QCoreApplication.translate("FrameToolCard", u"Name", None))
|
|
||||||
self.pushButtonInstall.setText(QCoreApplication.translate("FrameToolCard", u"\u5b89\u88c5", None))
|
|
||||||
self.pushButtonUninstall.setText(QCoreApplication.translate("FrameToolCard", u"\u5378\u8f7d", None))
|
|
||||||
self.pushButtonUpdate.setText(QCoreApplication.translate("FrameToolCard", u"\u66f4\u65b0", None))
|
|
||||||
self.labelInfo.setText(QCoreApplication.translate("FrameToolCard", u"TextLabel", None))
|
|
||||||
# retranslateUi
|
|
||||||
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
"""
|
|
||||||
工具箱模块
|
|
||||||
|
|
||||||
提供工具箱主窗口,包含各种实用工具的入口。
|
|
||||||
使用 PySide6 构建的窗口框架。
|
|
||||||
|
|
||||||
主要功能:
|
|
||||||
- 工具箱主窗口界面
|
|
||||||
- 窗口居中显示功能
|
|
||||||
- 工具分类和导航
|
|
||||||
|
|
||||||
Author: Model Team
|
|
||||||
Version: 0.0.1
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import logging
|
|
||||||
import importlib.util
|
|
||||||
|
|
||||||
from qt_material import apply_stylesheet
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
from .tools_ui import Ui_FormTools
|
|
||||||
from PySide6.QtGui import QIcon
|
|
||||||
|
|
||||||
from PySide6.QtWidgets import QWidget, QListWidgetItem
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
PLUGINS_PATH = Path('Y:/SE/xufeifei/plugins')
|
|
||||||
|
|
||||||
class ToolsWindow(QWidget, Ui_FormTools):
|
|
||||||
"""工具箱主窗口类
|
|
||||||
|
|
||||||
继承自 QWidget(Qt 窗口基类)和 Ui_FormTools(Qt Designer 生成的 UI 界面)
|
|
||||||
负责显示工具箱的主界面,提供工具的分类和导航功能。
|
|
||||||
|
|
||||||
窗口特性:
|
|
||||||
- 默认尺寸: 400x293 像素
|
|
||||||
- 支持窗口居中显示
|
|
||||||
- 可作为独立窗口或嵌入其他窗口使用
|
|
||||||
|
|
||||||
Attributes:
|
|
||||||
parent: 父窗口对象,默认为 None(顶级窗口)
|
|
||||||
"""
|
|
||||||
def __init__(self, tools:dict, parent: QWidget = None) -> None:
|
|
||||||
"""初始化工具箱窗口
|
|
||||||
|
|
||||||
创建工具箱窗口实例,初始化 UI 界面。
|
|
||||||
|
|
||||||
Args:
|
|
||||||
parent: 父窗口对象,用于建立父子关系。
|
|
||||||
默认为 None,表示这是顶级窗口。
|
|
||||||
"""
|
|
||||||
super().__init__(parent)
|
|
||||||
self.setupUi(self)
|
|
||||||
|
|
||||||
self.tools = tools
|
|
||||||
|
|
||||||
self.initUI()
|
|
||||||
self.init_tool_list()
|
|
||||||
self.load_stylesheet()
|
|
||||||
|
|
||||||
def initUI(self) -> None:
|
|
||||||
"""
|
|
||||||
初始化用户界面
|
|
||||||
|
|
||||||
配置窗口标题、图标、大小和居中显示。
|
|
||||||
"""
|
|
||||||
self.setWindowTitle("工具箱")
|
|
||||||
self.setWindowIcon(QIcon('resources/tools.ico'))
|
|
||||||
|
|
||||||
|
|
||||||
def load_stylesheet(self) -> None:
|
|
||||||
"""
|
|
||||||
加载 Qt 样式表和自定义样式文件
|
|
||||||
|
|
||||||
使用 qt_material 库加载暗色主题,并应用自定义 QSS 样式表
|
|
||||||
失败时记录错误日志,但不影响应用继续运行(降级策略)
|
|
||||||
|
|
||||||
异常处理:
|
|
||||||
- FileNotFoundError: 样式文件不存在
|
|
||||||
- RuntimeError: 主题加载失败
|
|
||||||
- 其他异常: 记录警告但不中断应用
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
apply_stylesheet(self, style=None,theme='dark_teal.xml', css_file='resources/my.qss')
|
|
||||||
except FileNotFoundError as e:
|
|
||||||
logger.warning(f"样式文件未找到,使用默认主题: {e}")
|
|
||||||
except RuntimeError as e:
|
|
||||||
logger.warning(f"主题加载失败,使用默认主题: {e}")
|
|
||||||
except Exception as e:
|
|
||||||
logger.warning(f"样式加载失败,使用默认主题: {e}")
|
|
||||||
|
|
||||||
def init_tool_list(self):
|
|
||||||
if not os.path.exists(PLUGINS_PATH):
|
|
||||||
logger.error("服务器链接错误!")
|
|
||||||
return
|
|
||||||
sys.path.append(str(PLUGINS_PATH))
|
|
||||||
|
|
||||||
for tool in Path(PLUGINS_PATH).glob("*.pyd"):
|
|
||||||
tool_name = tool.stem
|
|
||||||
try:
|
|
||||||
module = importlib.import_module(tool_name)
|
|
||||||
|
|
||||||
name = module.read_tool_name()
|
|
||||||
version = module.read_tool_version()
|
|
||||||
description = module.read_tool_description()
|
|
||||||
|
|
||||||
if name in self.tools.keys():
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.tools[name] = {}
|
|
||||||
self.tools[name]["version"] = version
|
|
||||||
self.tools[name]["description"] = description
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"{tool_name}无法加载:{str(e)}")
|
|
||||||
# if
|
|
||||||
sys.path.remove(str(PLUGINS_PATH))
|
|
||||||
|
|
||||||
def on_update_tool_card(self):
|
|
||||||
# for ke
|
|
||||||
# item = QListWidgetItem()
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
@@ -10,10 +10,12 @@ Model Team Tools - 主程序入口
|
|||||||
- 配置菜单栏和状态栏
|
- 配置菜单栏和状态栏
|
||||||
- 提供统一的日志记录接口
|
- 提供统一的日志记录接口
|
||||||
"""
|
"""
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
import core
|
import core
|
||||||
import traceback
|
import traceback
|
||||||
|
import importlib
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -33,6 +35,7 @@ MICRO_VER: int = 1 # 修订版本号
|
|||||||
APP_NAME: str = "Model Team Tools"
|
APP_NAME: str = "Model Team Tools"
|
||||||
APP_VERSION: str = f"{MAJOR_VER}.{MINOR_VER}.{MICRO_VER}"
|
APP_VERSION: str = f"{MAJOR_VER}.{MINOR_VER}.{MICRO_VER}"
|
||||||
|
|
||||||
|
LOCAL_PLUGINS_PATH = Path("./plugins")
|
||||||
|
|
||||||
class MainWindow(QMainWindow, Ui_MainWindow):
|
class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
"""
|
"""
|
||||||
@@ -45,9 +48,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.initUI()
|
|
||||||
|
|
||||||
self.tools = dict()
|
self.plugin_registry = core.PluginRegistry()
|
||||||
|
self.plugins = core.Plugins(self.plugin_registry)
|
||||||
|
self.plugin_registry.plugins_loader_signal.connect(self.on_plugins_loader)
|
||||||
|
|
||||||
|
self.initUI()
|
||||||
|
|
||||||
def initUI(self) -> None:
|
def initUI(self) -> None:
|
||||||
"""
|
"""
|
||||||
@@ -108,13 +114,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|||||||
- 打开失败时记录 ERROR 级别日志
|
- 打开失败时记录 ERROR 级别日志
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.tool_window = core.ToolsWindow(self.tools)
|
self.plugins.show()
|
||||||
self.tool_window.show()
|
|
||||||
# logger.info("工具箱窗口已打开")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"无法打开工具箱窗口: {e}")
|
logger.error(f"无法打开工具箱窗口: {e}")
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
def on_plugins_loader(self, plugins:dict):
|
||||||
|
for name in plugins.keys():
|
||||||
|
self.stackedWidget.addWidget(plugins[name]['obj'])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"DataPath": "",
|
||||||
|
"FilePath": "",
|
||||||
|
"AddTimeEn": true,
|
||||||
|
"GeratePath": true,
|
||||||
|
"CurrProject": "",
|
||||||
|
"ItemConfigs": {}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 512 512"><path fill="#1de9b6" d="M495.855 367.604c-28.98-73.177-53.037-148.231-80.725-221.893c-12.23-31.362-24.198-62.986-40.868-92.33c-6.62-10.535-12.956-22.119-23.814-28.86c-2.739-1.74-5.828-2.479-8.88-2.42c-5.084.096-10.14 2.37-14.025 5.65c-14.571 11.543-23.209 28.334-32.896 43.793c-17.114 28.698-35.156 58.748-63.773 77.396c-13.44 9.485-31.039 10.514-43.995 20.686c-17.72 13.36-29.767 32.31-44.298 48.737c-3.31 3.956-8.436 5.53-12.916 7.67C86.315 243.71 42.945 261.35 0 279.916c36.367 28.132 75.115 53.157 112.208 80.321c10.172-2.018 20.383-6.196 30.877-4.339c16.63 5.207 26.377 21.15 34.006 35.721c15.5 31.765 26.7 65.307 39.253 98.283c20.988-1.493 39.878-12.31 56.104-25.025c31.24-25.307 55.034-58.001 81.23-88.192c12.552-13.199 25.347-28.92 44.197-32.593c19.05-4.601 39.454 2.22 53.581 15.338c19.818 17.719 37.376 38.203 60.544 51.765c-3.108-15.338-10.575-29.101-16.145-43.592M171.844 316.04c-18.284 10.817-37.699 19.717-56.71 29.162c-29.828-19.98-58.889-41.15-88.192-61.856c39.515-17.315 79.635-33.4 119.675-49.545c18.97 14.813 38.547 28.88 57.517 43.693c-8.92 14.248-19.657 27.487-32.29 38.546m40.665-49.646c-18.85-14.167-37.94-27.951-56.508-42.482c11.907-16.226 24.945-31.906 40.565-44.701c10.333-6.62 22.966-8.456 33.703-14.43c25.469-12.714 42.845-36.044 59.434-58.324c-21.271 55.216-43.975 110.654-77.194 159.937"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
Reference in New Issue
Block a user