diff --git a/pyqt5fluentdesign/__pycache__/app_detail_window.cpython-312.pyc b/pyqt5fluentdesign/__pycache__/app_detail_window.cpython-312.pyc index 428fff3..c42b284 100644 Binary files a/pyqt5fluentdesign/__pycache__/app_detail_window.cpython-312.pyc and b/pyqt5fluentdesign/__pycache__/app_detail_window.cpython-312.pyc differ diff --git a/pyqt5fluentdesign/__pycache__/leonapp_gui.cpython-312.pyc b/pyqt5fluentdesign/__pycache__/leonapp_gui.cpython-312.pyc index cb201d4..436a509 100644 Binary files a/pyqt5fluentdesign/__pycache__/leonapp_gui.cpython-312.pyc and b/pyqt5fluentdesign/__pycache__/leonapp_gui.cpython-312.pyc differ 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")