From 0e54dce62a9f61fc47fe1e6bba94aaf254ab7f42 Mon Sep 17 00:00:00 2001 From: Leonmmcoset Date: Sat, 27 Sep 2025 21:53:54 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E9=85=8D=E7=BD=AE=E7=AE=A1=E7=90=86):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=85=8D=E7=BD=AE=E7=B3=BB=E7=BB=9F=E5=92=8C?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加基于QConfig的配置管理系统,支持自动打开安装程序和应用打开方式的设置 新增设置标签页用于管理应用配置 更新安装确认对话框以支持配置选项 将版本号更新为Prerelease 1 --- .../app_detail_window.cpython-312.pyc | Bin 42163 -> 43085 bytes .../__pycache__/leonapp_gui.cpython-312.pyc | Bin 127808 -> 132663 bytes pyqt5fluentdesign/app_detail_window.py | 139 +++++++++++------- pyqt5fluentdesign/config.json | 5 + pyqt5fluentdesign/config/config.json | 10 ++ pyqt5fluentdesign/leonapp_gui.py | 126 +++++++++++++++- 6 files changed, 223 insertions(+), 57 deletions(-) create mode 100644 pyqt5fluentdesign/config.json create mode 100644 pyqt5fluentdesign/config/config.json diff --git a/pyqt5fluentdesign/__pycache__/app_detail_window.cpython-312.pyc b/pyqt5fluentdesign/__pycache__/app_detail_window.cpython-312.pyc index 428fff3fab755edfade161096feef27e36fb8710..c42b2843c77e171756fe409d53efd38f1470f9b7 100644 GIT binary patch delta 5544 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 diff --git a/pyqt5fluentdesign/__pycache__/leonapp_gui.cpython-312.pyc b/pyqt5fluentdesign/__pycache__/leonapp_gui.cpython-312.pyc index cb201d4b0ee56ce254dcce4408c766334b261367..436a509d372ceced5a5d2f4e5bc44317aa9780a5 100644 GIT binary patch delta 24169 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 U)g8VK!~f^%Rg%@xDFUzke+_2zr2qf` diff --git a/pyqt5fluentdesign/app_detail_window.py b/pyqt5fluentdesign/app_detail_window.py index 2d30d35..fa62c60 100644 --- a/pyqt5fluentdesign/app_detail_window.py +++ b/pyqt5fluentdesign/app_detail_window.py @@ -666,49 +666,38 @@ class AppDetailWindow(QMainWindow): self.scroll_layout.addWidget(button_card) def install_app(self): """安装应用""" - from qfluentwidgets import InfoBar - from PyQt5.QtWidgets import QMessageBox, QProgressDialog + from qfluentwidgets import InfoBar, MessageBox + from PyQt5.QtWidgets import QProgressDialog + from leonapp_gui import get_global_settings # 检查是否有应用数据 if not hasattr(self, 'app_data'): show_error_dialog("错误", "应用数据未加载,请刷新页面后重试。") return - # 创建Sweet Alert风格的确认对话框 - confirm_box = QMessageBox() - confirm_box.setWindowTitle("确认安装") - confirm_box.setIcon(QMessageBox.Question) - confirm_box.setText(f"您确定要安装{self.app_data.get('name', '未知应用')}吗?\n\n点击'确定'开始安装。") + # 创建QFluentWidgets风格的确认对话框 + # 从全局设置获取默认的自动打开选项 + global_settings = get_global_settings() + default_auto_open = bool(global_settings.auto_open_installer) - # 设置字体大小 - font = QFont() - font.setPointSize(10) - confirm_box.setFont(font) + confirm_box = MessageBox("确认安装", f"您确定要安装{self.app_data.get('name', '未知应用')}吗?", self) - # 添加按钮 - confirm_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No) - confirm_box.setDefaultButton(QMessageBox.No) + # 添加自动打开复选框 + from PyQt5.QtWidgets import QCheckBox + self.auto_open_checkbox = QCheckBox("下载后自动打开安装程序", confirm_box) + self.auto_open_checkbox.setChecked(default_auto_open) # 使用全局设置作为默认值 + + # 将复选框添加到对话框中 + layout = confirm_box.layout() + layout.addWidget(self.auto_open_checkbox) # 显示对话框 - reply = confirm_box.exec_() + reply = confirm_box.exec() - if reply == QMessageBox.Yes: - # 创建Sweet Alert风格的成功提示 - success_box = QMessageBox() - success_box.setWindowTitle("安装开始") - success_box.setIcon(QMessageBox.Information) - success_box.setText(f"{self.app_data.get('name', '未知应用')}安装已开始,请稍候...") - - # 设置字体大小 - font = QFont() - font.setPointSize(10) - success_box.setFont(font) - - # 添加按钮 - success_box.setStandardButtons(QMessageBox.Ok) - - # 显示对话框 - success_box.exec_() + # 保存用户选择 + self.auto_open_installer = self.auto_open_checkbox.isChecked() + + if reply == 1: # QFluentWidgets的MessageBox返回1表示确认 # 1. 首先尝试从应用数据中获取直接下载链接 download_url = self.app_data.get('direct_download_url') @@ -798,7 +787,12 @@ class AppDetailWindow(QMainWindow): self.progress_dialog.setMinimumDuration(0) # 创建保存路径 - 使用代码文件夹所在的install目录 - file_extension = ".exe" # 假设是Windows可执行文件 + # 从下载URL中提取文件扩展名 + import os + _, file_extension = os.path.splitext(download_url) + # 如果没有扩展名或者扩展名不合法,使用默认扩展名.zip + if not file_extension or len(file_extension) < 2: + file_extension = ".zip" app_name = self.app_data.get('name', '未知应用').replace(' ', '_') # 获取当前脚本所在目录 @@ -843,32 +837,69 @@ class AppDetailWindow(QMainWindow): # 根据操作系统执行不同的安装操作 if platform.system() == "Windows": try: - # 在Windows上,直接运行可执行文件 - subprocess.Popen([file_path], shell=True) + # 使用MessageBox显示下载完成提示 + from qfluentwidgets import MessageBox - # 创建Sweet Alert风格的下载完成提示 - success_box = QMessageBox() - success_box.setWindowTitle("下载完成") - success_box.setIcon(QMessageBox.Information) - success_box.setText(f"安装程序已启动,请按照向导完成安装。\n文件位置:{file_path}") + # 导入全局设置 + from leonapp_gui import get_global_settings + global_settings = get_global_settings() + app_open_method = global_settings.app_open_method - # 设置字体大小 - font = QFont() - font.setPointSize(10) - success_box.setFont(font) + # 根据用户选择决定是否自动打开安装程序 + if hasattr(self, 'auto_open_installer') and self.auto_open_installer: + try: + # 根据配置的应用打开方式执行不同的操作 + # 0: Windows直接运行应用程序, 1: 打开文件夹方式 + if app_open_method == 0: # Windows直接运行应用程序 + # 根据文件扩展名决定如何处理 + import os + _, ext = os.path.splitext(file_path) + ext = ext.lower() + + # 对于可执行文件,直接运行 + if ext in [".exe", ".msi", ".bat", ".cmd"]: + subprocess.Popen([file_path], shell=True) + # 对于其他文件类型,使用系统默认程序打开 + else: + os.startfile(file_path) + + download_box = MessageBox("下载完成", f"安装程序已启动,请按照向导完成安装。\n文件位置:{file_path}", self) + download_box.exec() + return # 成功打开安装程序后不需要再打开文件夹 + else: # 打开文件夹方式 + # 打开下载文件夹并选中文件 + subprocess.Popen(f'explorer /select,"{file_path}"') + download_box = MessageBox("下载完成", f"文件已下载完成,文件夹已打开。\n文件位置:{file_path}", self) + download_box.exec() + return + except Exception as e: + show_error_dialog("操作失败", f"无法执行操作: {str(e)}\n您可以手动运行文件: {file_path}") + else: + # 不自动打开,只显示下载完成信息 + download_box = MessageBox("下载完成", f"文件已下载完成。\n文件位置:{file_path}", self) + download_box.exec() - # 添加按钮 - success_box.setStandardButtons(QMessageBox.Ok) - - # 显示对话框 - success_box.exec_() - - # 打开下载文件夹并选中文件 - subprocess.Popen(f'explorer /select,"{file_path}"') + # 如果没有自动打开,或者自动打开失败后,根据配置决定默认行为 + if app_open_method == 0: # 默认直接运行应用程序 + try: + import os + _, ext = os.path.splitext(file_path) + ext = ext.lower() + + if ext in [".exe", ".msi", ".bat", ".cmd"]: + subprocess.Popen([file_path], shell=True) + else: + os.startfile(file_path) + except Exception: + # 如果运行失败,回退到打开文件夹 + subprocess.Popen(f'explorer /select,"{file_path}"') + else: # 默认打开文件夹 + # 打开下载文件夹并选中文件 + subprocess.Popen(f'explorer /select,"{file_path}"') except Exception as e: - show_error_dialog("启动安装程序失败", f"无法启动安装程序: {str(e)}\n您可以手动运行文件: {file_path}") + show_error_dialog("操作失败", f"无法执行操作: {str(e)}\n您可以手动运行文件: {file_path}") - # 即使启动安装程序失败,也尝试打开下载文件夹 + # 即使操作失败,也尝试打开下载文件夹 try: subprocess.Popen(f'explorer /select,"{file_path}"') except Exception as ex: diff --git a/pyqt5fluentdesign/config.json b/pyqt5fluentdesign/config.json new file mode 100644 index 0000000..2787944 --- /dev/null +++ b/pyqt5fluentdesign/config.json @@ -0,0 +1,5 @@ +{ + "General": { + "AutoOpenInstaller": true + } +} \ No newline at end of file diff --git a/pyqt5fluentdesign/config/config.json b/pyqt5fluentdesign/config/config.json new file mode 100644 index 0000000..301aea2 --- /dev/null +++ b/pyqt5fluentdesign/config/config.json @@ -0,0 +1,10 @@ +{ + "General": { + "AppOpenMethod": 1, + "AutoOpenInstaller": false + }, + "QFluentWidgets": { + "ThemeColor": "#ff009faa", + "ThemeMode": "Light" + } +} \ No newline at end of file diff --git a/pyqt5fluentdesign/leonapp_gui.py b/pyqt5fluentdesign/leonapp_gui.py index 78c2da7..d306e19 100644 --- a/pyqt5fluentdesign/leonapp_gui.py +++ b/pyqt5fluentdesign/leonapp_gui.py @@ -26,7 +26,7 @@ LeonApp GUI - 基于PyQt5和Fluent Design的App Store API图形界面工具 # # APP版本号 -APP_VERSION = "Beta 0.4" +APP_VERSION = "Prerelease 1" import sys import json @@ -46,11 +46,41 @@ from qfluentwidgets import ( CardWidget, TitleLabel, SubtitleLabel, CaptionLabel, BodyLabel, PushButton, PrimaryPushButton, LineEdit, ComboBox, ProgressBar, TableWidget, ScrollArea, InfoBar, InfoBarPosition, NavigationInterface, NavigationItemPosition, - FluentWindow, MSFluentWindow, FluentIcon, SimpleCardWidget, PrimaryPushSettingCard + FluentWindow, MSFluentWindow, FluentIcon, SimpleCardWidget, PrimaryPushSettingCard, + OptionsSettingCard, QConfig, ConfigItem, OptionsConfigItem, BoolValidator, OptionsValidator, qconfig ) from qfluentwidgets import FluentTranslator from app_detail_window import AppDetailWindow +# 配置管理 - 使用QConfig管理配置 +class AppConfig(QConfig): + """应用配置类""" + # 常规设置 + auto_open_installer = OptionsConfigItem( + "General", "AutoOpenInstaller", True, + OptionsValidator([True, False]) + ) + + # 应用打开方式 + # 0: Windows直接运行应用程序, 1: 打开文件夹方式 + app_open_method = OptionsConfigItem( + "General", "AppOpenMethod", 0, + OptionsValidator([0, 1]) + ) + +# 创建配置文件目录 +config_dir = os.path.join(os.path.dirname(__file__), "config") +os.makedirs(config_dir, exist_ok=True) + +# 创建配置实例并使用配置文件来初始化它 +app_config = AppConfig() +config_path = os.path.join(config_dir, "config.json") +qconfig.load(config_path, app_config) + +def get_global_settings(): + """获取全局配置""" + return app_config + class APIClient: """API客户端类,处理与API的通信""" def __init__(self, api_base_url="http://leonmmcoset.jjxmm.win:8010/api.php"): @@ -2562,8 +2592,93 @@ class AppInfoTab(QWidget): parent=self ) +class SettingsTab(QWidget): + """设置标签页""" + def __init__(self, parent=None): + super().__init__(parent) + self.parent = parent + self.init_ui() + + def init_ui(self): + """初始化UI""" + # 创建主布局 + self.main_layout = QVBoxLayout(self) + + # 创建滚动区域 + self.scroll_area = ScrollArea(self) + self.scroll_area.setWidgetResizable(True) + + # 创建滚动内容控件 + self.scroll_content = QWidget() + self.scroll_layout = QVBoxLayout(self.scroll_content) + self.scroll_layout.setContentsMargins(20, 20, 20, 20) + + # 创建常规设置卡片 + general_card = CardWidget(self.scroll_content) + general_layout = QVBoxLayout(general_card) + general_layout.setContentsMargins(20, 20, 20, 20) + + # 添加卡片标题 + title = TitleLabel("常规设置", general_card) + general_layout.addWidget(title) + general_layout.addSpacing(16) + + # 添加自动打开安装程序选项 + from qfluentwidgets import FluentIcon, OptionsValidator + + # 创建OptionsSettingCard,直接使用configItem + self.auto_open_option = OptionsSettingCard( + icon=FluentIcon.SETTING, + title="下载后自动打开安装程序", + content="设置是否在下载完成后自动打开安装程序", + texts=["是", "否"], + configItem=app_config.auto_open_installer, + parent=general_card + ) + + # 连接信号 + self.auto_open_option.optionChanged.connect(self.on_auto_open_changed) + + general_layout.addWidget(self.auto_open_option) + + # 添加应用打开方式选项 + self.app_open_method_option = OptionsSettingCard( + icon=FluentIcon.SHARE, + title="应用打开方式", + content="选择下载完成后如何打开应用程序", + texts=["Windows直接运行应用程序", "打开文件夹方式"], + configItem=app_config.app_open_method, + parent=general_card + ) + + # 连接信号 + self.app_open_method_option.optionChanged.connect(self.on_app_open_method_changed) + + general_layout.addWidget(self.app_open_method_option) + + # 将常规设置卡片添加到布局 + self.scroll_layout.addWidget(general_card) + + # 添加底部间距 + self.scroll_layout.addSpacing(20) + + # 设置滚动区域的内容 + self.scroll_area.setWidget(self.scroll_content) + + # 将滚动区域添加到主布局 + self.main_layout.addWidget(self.scroll_area) + + def on_auto_open_changed(self, index): + """自动打开设置变更处理""" + app_config.auto_open_installer = (index == 0) + + def on_app_open_method_changed(self, index): + """应用打开方式设置变更处理""" + app_config.app_open_method = index + class LeonAppGUI(MSFluentWindow): - """主应用窗口""" + """主窗口类""" + def __init__(self): super().__init__() # 初始化API客户端 @@ -2619,6 +2734,11 @@ class LeonAppGUI(MSFluentWindow): self.info_tab.setObjectName("info") self.addSubInterface(self.info_tab, FluentIcon.INFO, "应用信息") + # 添加设置标签页 + self.settings_tab = SettingsTab(self) + self.settings_tab.setObjectName("settings") + self.addSubInterface(self.settings_tab, FluentIcon.SETTING, "设置") + # 设置默认选中的标签页 self.navigationInterface.setCurrentItem("homepage")