feat(配置管理): 添加配置系统和设置界面
添加基于QConfig的配置管理系统,支持自动打开安装程序和应用打开方式的设置 新增设置标签页用于管理应用配置 更新安装确认对话框以支持配置选项 将版本号更新为Prerelease 1
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -666,49 +666,38 @@ class AppDetailWindow(QMainWindow):
|
|||||||
self.scroll_layout.addWidget(button_card)
|
self.scroll_layout.addWidget(button_card)
|
||||||
def install_app(self):
|
def install_app(self):
|
||||||
"""安装应用"""
|
"""安装应用"""
|
||||||
from qfluentwidgets import InfoBar
|
from qfluentwidgets import InfoBar, MessageBox
|
||||||
from PyQt5.QtWidgets import QMessageBox, QProgressDialog
|
from PyQt5.QtWidgets import QProgressDialog
|
||||||
|
from leonapp_gui import get_global_settings
|
||||||
|
|
||||||
# 检查是否有应用数据
|
# 检查是否有应用数据
|
||||||
if not hasattr(self, 'app_data'):
|
if not hasattr(self, 'app_data'):
|
||||||
show_error_dialog("错误", "应用数据未加载,请刷新页面后重试。")
|
show_error_dialog("错误", "应用数据未加载,请刷新页面后重试。")
|
||||||
return
|
return
|
||||||
|
|
||||||
# 创建Sweet Alert风格的确认对话框
|
# 创建QFluentWidgets风格的确认对话框
|
||||||
confirm_box = QMessageBox()
|
# 从全局设置获取默认的自动打开选项
|
||||||
confirm_box.setWindowTitle("确认安装")
|
global_settings = get_global_settings()
|
||||||
confirm_box.setIcon(QMessageBox.Question)
|
default_auto_open = bool(global_settings.auto_open_installer)
|
||||||
confirm_box.setText(f"您确定要安装{self.app_data.get('name', '未知应用')}吗?\n\n点击'确定'开始安装。")
|
|
||||||
|
|
||||||
# 设置字体大小
|
confirm_box = MessageBox("确认安装", f"您确定要安装{self.app_data.get('name', '未知应用')}吗?", self)
|
||||||
font = QFont()
|
|
||||||
font.setPointSize(10)
|
|
||||||
confirm_box.setFont(font)
|
|
||||||
|
|
||||||
# 添加按钮
|
# 添加自动打开复选框
|
||||||
confirm_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
|
from PyQt5.QtWidgets import QCheckBox
|
||||||
confirm_box.setDefaultButton(QMessageBox.No)
|
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风格的成功提示
|
self.auto_open_installer = self.auto_open_checkbox.isChecked()
|
||||||
success_box = QMessageBox()
|
|
||||||
success_box.setWindowTitle("安装开始")
|
|
||||||
success_box.setIcon(QMessageBox.Information)
|
|
||||||
success_box.setText(f"{self.app_data.get('name', '未知应用')}安装已开始,请稍候...")
|
|
||||||
|
|
||||||
# 设置字体大小
|
if reply == 1: # QFluentWidgets的MessageBox返回1表示确认
|
||||||
font = QFont()
|
|
||||||
font.setPointSize(10)
|
|
||||||
success_box.setFont(font)
|
|
||||||
|
|
||||||
# 添加按钮
|
|
||||||
success_box.setStandardButtons(QMessageBox.Ok)
|
|
||||||
|
|
||||||
# 显示对话框
|
|
||||||
success_box.exec_()
|
|
||||||
|
|
||||||
# 1. 首先尝试从应用数据中获取直接下载链接
|
# 1. 首先尝试从应用数据中获取直接下载链接
|
||||||
download_url = self.app_data.get('direct_download_url')
|
download_url = self.app_data.get('direct_download_url')
|
||||||
@@ -798,7 +787,12 @@ class AppDetailWindow(QMainWindow):
|
|||||||
self.progress_dialog.setMinimumDuration(0)
|
self.progress_dialog.setMinimumDuration(0)
|
||||||
|
|
||||||
# 创建保存路径 - 使用代码文件夹所在的install目录
|
# 创建保存路径 - 使用代码文件夹所在的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(' ', '_')
|
app_name = self.app_data.get('name', '未知应用').replace(' ', '_')
|
||||||
|
|
||||||
# 获取当前脚本所在目录
|
# 获取当前脚本所在目录
|
||||||
@@ -843,32 +837,69 @@ class AppDetailWindow(QMainWindow):
|
|||||||
# 根据操作系统执行不同的安装操作
|
# 根据操作系统执行不同的安装操作
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
try:
|
try:
|
||||||
# 在Windows上,直接运行可执行文件
|
# 使用MessageBox显示下载完成提示
|
||||||
subprocess.Popen([file_path], shell=True)
|
from qfluentwidgets import MessageBox
|
||||||
|
|
||||||
# 创建Sweet Alert风格的下载完成提示
|
# 导入全局设置
|
||||||
success_box = QMessageBox()
|
from leonapp_gui import get_global_settings
|
||||||
success_box.setWindowTitle("下载完成")
|
global_settings = get_global_settings()
|
||||||
success_box.setIcon(QMessageBox.Information)
|
app_open_method = global_settings.app_open_method
|
||||||
success_box.setText(f"安装程序已启动,请按照向导完成安装。\n文件位置:{file_path}")
|
|
||||||
|
|
||||||
# 设置字体大小
|
# 根据用户选择决定是否自动打开安装程序
|
||||||
font = QFont()
|
if hasattr(self, 'auto_open_installer') and self.auto_open_installer:
|
||||||
font.setPointSize(10)
|
try:
|
||||||
success_box.setFont(font)
|
# 根据配置的应用打开方式执行不同的操作
|
||||||
|
# 0: Windows直接运行应用程序, 1: 打开文件夹方式
|
||||||
|
if app_open_method == 0: # Windows直接运行应用程序
|
||||||
|
# 根据文件扩展名决定如何处理
|
||||||
|
import os
|
||||||
|
_, ext = os.path.splitext(file_path)
|
||||||
|
ext = ext.lower()
|
||||||
|
|
||||||
# 添加按钮
|
# 对于可执行文件,直接运行
|
||||||
success_box.setStandardButtons(QMessageBox.Ok)
|
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)
|
||||||
success_box.exec_()
|
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()
|
||||||
|
|
||||||
# 打开下载文件夹并选中文件
|
# 如果没有自动打开,或者自动打开失败后,根据配置决定默认行为
|
||||||
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:
|
except Exception as e:
|
||||||
show_error_dialog("启动安装程序失败", f"无法启动安装程序: {str(e)}\n您可以手动运行文件: {file_path}")
|
show_error_dialog("操作失败", f"无法执行操作: {str(e)}\n您可以手动运行文件: {file_path}")
|
||||||
|
|
||||||
# 即使启动安装程序失败,也尝试打开下载文件夹
|
# 即使操作失败,也尝试打开下载文件夹
|
||||||
try:
|
try:
|
||||||
subprocess.Popen(f'explorer /select,"{file_path}"')
|
subprocess.Popen(f'explorer /select,"{file_path}"')
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
|
|||||||
5
pyqt5fluentdesign/config.json
Normal file
5
pyqt5fluentdesign/config.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"General": {
|
||||||
|
"AutoOpenInstaller": true
|
||||||
|
}
|
||||||
|
}
|
||||||
10
pyqt5fluentdesign/config/config.json
Normal file
10
pyqt5fluentdesign/config/config.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"General": {
|
||||||
|
"AppOpenMethod": 1,
|
||||||
|
"AutoOpenInstaller": false
|
||||||
|
},
|
||||||
|
"QFluentWidgets": {
|
||||||
|
"ThemeColor": "#ff009faa",
|
||||||
|
"ThemeMode": "Light"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,7 @@ LeonApp GUI - 基于PyQt5和Fluent Design的App Store API图形界面工具
|
|||||||
#
|
#
|
||||||
|
|
||||||
# APP版本号
|
# APP版本号
|
||||||
APP_VERSION = "Beta 0.4"
|
APP_VERSION = "Prerelease 1"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
@@ -46,11 +46,41 @@ from qfluentwidgets import (
|
|||||||
CardWidget, TitleLabel, SubtitleLabel, CaptionLabel, BodyLabel, PushButton,
|
CardWidget, TitleLabel, SubtitleLabel, CaptionLabel, BodyLabel, PushButton,
|
||||||
PrimaryPushButton, LineEdit, ComboBox, ProgressBar, TableWidget,
|
PrimaryPushButton, LineEdit, ComboBox, ProgressBar, TableWidget,
|
||||||
ScrollArea, InfoBar, InfoBarPosition, NavigationInterface, NavigationItemPosition,
|
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 qfluentwidgets import FluentTranslator
|
||||||
from app_detail_window import AppDetailWindow
|
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:
|
class APIClient:
|
||||||
"""API客户端类,处理与API的通信"""
|
"""API客户端类,处理与API的通信"""
|
||||||
def __init__(self, api_base_url="http://leonmmcoset.jjxmm.win:8010/api.php"):
|
def __init__(self, api_base_url="http://leonmmcoset.jjxmm.win:8010/api.php"):
|
||||||
@@ -2562,8 +2592,93 @@ class AppInfoTab(QWidget):
|
|||||||
parent=self
|
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):
|
class LeonAppGUI(MSFluentWindow):
|
||||||
"""主应用窗口"""
|
"""主窗口类"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
# 初始化API客户端
|
# 初始化API客户端
|
||||||
@@ -2619,6 +2734,11 @@ class LeonAppGUI(MSFluentWindow):
|
|||||||
self.info_tab.setObjectName("info")
|
self.info_tab.setObjectName("info")
|
||||||
self.addSubInterface(self.info_tab, FluentIcon.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")
|
self.navigationInterface.setCurrentItem("homepage")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user