diff --git a/source/core/animations.py b/source/core/animations.py index 239ba1d..f6ffdee 100644 --- a/source/core/animations.py +++ b/source/core/animations.py @@ -185,6 +185,11 @@ class MultiStageAnimations(QObject): widget.setGraphicsEffect(effect) widget.move(widget.x(), self.canvas_height + 100) widget.show() + + # 禁用所有按钮,直到动画完成 + self.ui.start_install_btn.setEnabled(False) + self.ui.uninstall_btn.setEnabled(False) + self.ui.exit_btn.setEnabled(False) def start_logo_animations(self): """启动Logo动画序列""" @@ -337,6 +342,12 @@ class MultiStageAnimations(QObject): def start_animations(self): """启动完整动画序列""" self.clear_animations() + + # 确保按钮在动画开始时被禁用 + self.ui.start_install_btn.setEnabled(False) + self.ui.uninstall_btn.setEnabled(False) + self.ui.exit_btn.setEnabled(False) + self.start_logo_animations() def clear_animations(self): diff --git a/source/core/download_manager.py b/source/core/download_manager.py index 67557e4..981f23b 100644 --- a/source/core/download_manager.py +++ b/source/core/download_manager.py @@ -10,7 +10,7 @@ from PySide6.QtCore import Qt from PySide6.QtGui import QIcon, QPixmap, QFont from utils import msgbox_frame, HostsManager, resource_path -from data.config import APP_NAME, PLUGIN, GAME_INFO, UA, CONFIG_URL +from data.config import APP_NAME, PLUGIN, GAME_INFO, UA, CONFIG_URL, DOWNLOAD_THREADS, DEFAULT_DOWNLOAD_THREAD_LEVEL from workers import IpOptimizerThread class DownloadManager: @@ -28,7 +28,9 @@ class DownloadManager: self.optimized_ip = None self.optimization_done = False # 标记是否已执行过优选 self.optimizing_msg_box = None - + # 添加下载线程级别 + self.download_thread_level = DEFAULT_DOWNLOAD_THREAD_LEVEL + def file_dialog(self): """显示文件夹选择对话框,选择游戏安装目录""" self.selected_folder = QtWidgets.QFileDialog.getExistingDirectory( @@ -903,4 +905,142 @@ class DownloadManager: self.main_window, f"已取消 - {APP_NAME}", "\n已成功取消安装进程。\n" - ) \ No newline at end of file + ) + + def get_download_thread_count(self): + """获取当前下载线程设置对应的线程数 + + Returns: + int: 下载线程数 + """ + # 获取当前线程级别对应的线程数 + thread_count = DOWNLOAD_THREADS.get(self.download_thread_level, DOWNLOAD_THREADS["medium"]) + return thread_count + + def set_download_thread_level(self, level): + """设置下载线程级别 + + Args: + level: 线程级别 (low, medium, high, extreme, insane) + + Returns: + bool: 设置是否成功 + """ + if level in DOWNLOAD_THREADS: + old_level = self.download_thread_level + self.download_thread_level = level + + # 只有非极端级别才保存到配置 + if level not in ["extreme", "insane"]: + if hasattr(self.main_window, 'config'): + self.main_window.config["download_thread_level"] = level + self.main_window.save_config(self.main_window.config) + + return True + return False + + def show_download_thread_settings(self): + """显示下载线程设置对话框""" + # 创建对话框 + from PySide6.QtWidgets import QDialog, QVBoxLayout, QRadioButton, QPushButton, QLabel, QButtonGroup, QHBoxLayout + from PySide6.QtCore import Qt + + dialog = QDialog(self.main_window) + dialog.setWindowTitle(f"下载线程设置 - {APP_NAME}") + dialog.setMinimumWidth(350) + + layout = QVBoxLayout(dialog) + + # 添加说明标签 + info_label = QLabel("选择下载线程数量(更多线程通常可以提高下载速度):", dialog) + info_label.setWordWrap(True) + layout.addWidget(info_label) + + # 创建按钮组 + button_group = QButtonGroup(dialog) + + # 添加线程选项 + thread_options = { + "low": f"低速 - {DOWNLOAD_THREADS['low']}线程(慢慢来,不着急)", + "medium": f"中速 - {DOWNLOAD_THREADS['medium']}线程(快人半步)", + "high": f"高速 - {DOWNLOAD_THREADS['high']}线程(默认,推荐配置)", + "extreme": f"极速 - {DOWNLOAD_THREADS['extreme']}线程(如果你对你的网和电脑很自信的话)", + "insane": f"狂暴 - {DOWNLOAD_THREADS['insane']}线程(看看是带宽和性能先榨干还是牛牛先榨干)" + } + + radio_buttons = {} + + for level, text in thread_options.items(): + radio = QRadioButton(text, dialog) + + # 选中当前使用的线程级别 + if level == self.download_thread_level: + radio.setChecked(True) + + button_group.addButton(radio) + layout.addWidget(radio) + radio_buttons[level] = radio + + layout.addSpacing(10) + + # 添加按钮区域 + btn_layout = QHBoxLayout() + + ok_button = QPushButton("确定", dialog) + cancel_button = QPushButton("取消", dialog) + + btn_layout.addWidget(ok_button) + btn_layout.addWidget(cancel_button) + + layout.addLayout(btn_layout) + + # 连接按钮事件 + ok_button.clicked.connect(dialog.accept) + cancel_button.clicked.connect(dialog.reject) + + # 显示对话框 + result = dialog.exec() + + # 处理结果 + if result == QDialog.DialogCode.Accepted: + # 获取用户选择的线程级别 + selected_level = None + for level, radio in radio_buttons.items(): + if radio.isChecked(): + selected_level = level + break + + if selected_level: + # 为极速和狂暴模式显示警告 + if selected_level in ["extreme", "insane"]: + warning_result = QtWidgets.QMessageBox.warning( + self.main_window, + f"高风险警告 - {APP_NAME}", + "警告!过高的线程数可能导致CPU负载过高或其他恶性问题!\n你确定要这么做吗?", + QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No, + QtWidgets.QMessageBox.StandardButton.No + ) + + if warning_result != QtWidgets.QMessageBox.StandardButton.Yes: + return False + + success = self.set_download_thread_level(selected_level) + + if success: + # 显示设置成功消息 + thread_count = DOWNLOAD_THREADS[selected_level] + message = f"\n已成功设置下载线程为: {thread_count}线程\n" + + # 对于极速和狂暴模式,添加仅本次生效的提示 + if selected_level in ["extreme", "insane"]: + message += "\n注意:极速/狂暴模式仅本次生效。软件重启后将恢复默认设置。\n" + + QtWidgets.QMessageBox.information( + self.main_window, + f"设置成功 - {APP_NAME}", + message + ) + + return True + + return False \ No newline at end of file diff --git a/source/core/ui_manager.py b/source/core/ui_manager.py index b8e10ff..f19385e 100644 --- a/source/core/ui_manager.py +++ b/source/core/ui_manager.py @@ -321,14 +321,29 @@ class UIManager: self.debug_submenu.addAction(self.debug_action) self.debug_submenu.addAction(self.open_log_action) - # 为未来功能预留的"修改下载源"按钮 - 现在点击时显示"正在开发中" + # 创建下载设置子菜单 + self.download_settings_menu = QMenu("下载设置", self.main_window) + self.download_settings_menu.setFont(menu_font) + self.download_settings_menu.setStyleSheet(menu_style) + + # "修改下载源"按钮移至下载设置菜单 self.switch_source_action = QAction("修改下载源", self.main_window) - self.switch_source_action.setFont(menu_font) # 设置自定义字体 - self.switch_source_action.setEnabled(True) # 启用但显示"正在开发中" + self.switch_source_action.setFont(menu_font) + self.switch_source_action.setEnabled(True) self.switch_source_action.triggered.connect(self.show_under_development) + # 添加下载线程设置选项 + self.thread_settings_action = QAction("下载线程设置", self.main_window) + self.thread_settings_action.setFont(menu_font) + # 连接到下载线程设置对话框 + self.thread_settings_action.triggered.connect(self.show_download_thread_settings) + + # 添加到下载设置子菜单 + self.download_settings_menu.addAction(self.switch_source_action) + self.download_settings_menu.addAction(self.thread_settings_action) + # 添加到主菜单 - self.ui.menu.addAction(self.switch_source_action) + self.ui.menu.addMenu(self.download_settings_menu) # 添加下载设置子菜单 self.ui.menu.addSeparator() self.ui.menu.addMenu(self.dev_menu) # 添加开发者选项子菜单 @@ -450,6 +465,19 @@ class UIManager: ) msg_box.exec() + def show_download_thread_settings(self): + """显示下载线程设置对话框""" + if hasattr(self.main_window, 'download_manager'): + self.main_window.download_manager.show_download_thread_settings() + else: + # 如果下载管理器不可用,显示错误信息 + msg_box = msgbox_frame( + f"错误 - {APP_NAME}", + "\n下载管理器未初始化,无法修改下载线程设置。\n", + QMessageBox.StandardButton.Ok, + ) + msg_box.exec() + def open_log_file(self): """打开log.txt文件""" if os.path.exists(LOG_FILE): diff --git a/source/data/config.py b/source/data/config.py index 91c0e3d..1f82655 100644 --- a/source/data/config.py +++ b/source/data/config.py @@ -63,4 +63,16 @@ GAME_INFO = app_data["game_info"] BLOCK_SIZE = 67108864 HASH_SIZE = 134217728 PLUGIN_HASH = {game: info["hash"] for game, info in GAME_INFO.items()} -PROCESS_INFO = {info["exe"]: game for game, info in GAME_INFO.items()} \ No newline at end of file +PROCESS_INFO = {info["exe"]: game for game, info in GAME_INFO.items()} + +# 下载线程档位设置 +DOWNLOAD_THREADS = { + "low": 1, # 低速 + "medium": 8, # 中速(默认) + "high": 16, # 高速 + "extreme": 32, # 极速 + "insane": 64 # 狂暴 +} + +# 默认下载线程档位 +DEFAULT_DOWNLOAD_THREAD_LEVEL = "high" \ No newline at end of file diff --git a/source/main_window.py b/source/main_window.py index 030b46a..7b281b0 100644 --- a/source/main_window.py +++ b/source/main_window.py @@ -1,5 +1,6 @@ import os import sys +import subprocess import shutil import json import webbrowser @@ -13,7 +14,8 @@ from PySide6.QtGui import QAction # Added for menu actions from ui.Ui_install import Ui_MainWindows from data.config import ( APP_NAME, PLUGIN, GAME_INFO, BLOCK_SIZE, - PLUGIN_HASH, UA, CONFIG_URL, LOG_FILE + PLUGIN_HASH, UA, CONFIG_URL, LOG_FILE, + DOWNLOAD_THREADS, DEFAULT_DOWNLOAD_THREAD_LEVEL # 添加下载线程常量 ) from utils import ( load_config, save_config, HashManager, AdminPrivileges, msgbox_frame, load_image_from_file @@ -72,6 +74,10 @@ class MainWindow(QMainWindow): # 初始化下载管理器 - 应该放在其他管理器之后,因为它可能依赖于它们 self.download_manager = DownloadManager(self) + # 加载用户下载线程设置 + if "download_thread_level" in self.config and self.config["download_thread_level"] in DOWNLOAD_THREADS: + self.download_manager.download_thread_level = self.config["download_thread_level"] + # 初始化状态变量 self.cloud_config = None self.config_valid = False # 添加配置有效标志 @@ -159,6 +165,11 @@ class MainWindow(QMainWindow): """动画完成后启用按钮""" self.animation_in_progress = False + # 启用所有菜单按钮 + self.ui.start_install_btn.setEnabled(True) + self.ui.uninstall_btn.setEnabled(True) + self.ui.exit_btn.setEnabled(True) + # 只有在配置有效时才启用开始安装按钮 if self.config_valid: self.set_start_button_enabled(True) @@ -246,12 +257,13 @@ class MainWindow(QMainWindow): Args: url: 下载URL _7z_path: 7z文件保存路径 - game_version: 游戏版本 + game_version: 游戏版本名称 Returns: DownloadThread: 下载线程实例 """ - return DownloadThread(url, _7z_path, game_version, self) + from workers import DownloadThread + return DownloadThread(url, _7z_path, game_version, parent=self) def create_progress_window(self): """创建下载进度窗口 diff --git a/source/workers/download.py b/source/workers/download.py index 418458b..b44b2c5 100644 --- a/source/workers/download.py +++ b/source/workers/download.py @@ -154,6 +154,12 @@ class DownloadThread(QThread): aria2c_path, ] + # 获取主窗口的下载管理器对象 + thread_count = 64 # 默认值 + if hasattr(self.parent(), 'download_manager'): + # 从下载管理器获取线程数设置 + thread_count = self.parent().download_manager.get_download_thread_count() + # 将所有的优化参数应用于每个下载任务 command.extend([ '--dir', download_dir, @@ -181,7 +187,7 @@ class DownloadThread(QThread): '--auto-file-renaming=false', '--allow-overwrite=true', '--split=128', - '--max-connection-per-server=64', + f'--max-connection-per-server={thread_count}', # 使用动态的线程数 '--min-split-size=1M', # 减小最小分片大小 '--optimize-concurrent-downloads=true', # 优化并发下载 '--file-allocation=none', # 禁用文件预分配加快开始