feat(core): 添加下载线程设置功能

- 在下载管理器中引入下载线程级别设置,支持用户自定义线程数
- 在主菜单中添加下载设置子菜单,包含修改下载源和下载线程设置选项
- 优化下载流程,动态调整下载线程数以提高下载效率
- 在动画过程中禁用相关按钮,确保用户体验流畅
- 更新配置文件,增加下载线程档位设置
This commit is contained in:
hyb-oyqq
2025-08-01 16:34:30 +08:00
parent a93991ca9d
commit 5c06802f65
6 changed files with 221 additions and 12 deletions

View File

@@ -185,6 +185,11 @@ class MultiStageAnimations(QObject):
widget.setGraphicsEffect(effect) widget.setGraphicsEffect(effect)
widget.move(widget.x(), self.canvas_height + 100) widget.move(widget.x(), self.canvas_height + 100)
widget.show() 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): def start_logo_animations(self):
"""启动Logo动画序列""" """启动Logo动画序列"""
@@ -337,6 +342,12 @@ class MultiStageAnimations(QObject):
def start_animations(self): def start_animations(self):
"""启动完整动画序列""" """启动完整动画序列"""
self.clear_animations() 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() self.start_logo_animations()
def clear_animations(self): def clear_animations(self):

View File

@@ -10,7 +10,7 @@ from PySide6.QtCore import Qt
from PySide6.QtGui import QIcon, QPixmap, QFont from PySide6.QtGui import QIcon, QPixmap, QFont
from utils import msgbox_frame, HostsManager, resource_path 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 from workers import IpOptimizerThread
class DownloadManager: class DownloadManager:
@@ -28,7 +28,9 @@ class DownloadManager:
self.optimized_ip = None self.optimized_ip = None
self.optimization_done = False # 标记是否已执行过优选 self.optimization_done = False # 标记是否已执行过优选
self.optimizing_msg_box = None self.optimizing_msg_box = None
# 添加下载线程级别
self.download_thread_level = DEFAULT_DOWNLOAD_THREAD_LEVEL
def file_dialog(self): def file_dialog(self):
"""显示文件夹选择对话框,选择游戏安装目录""" """显示文件夹选择对话框,选择游戏安装目录"""
self.selected_folder = QtWidgets.QFileDialog.getExistingDirectory( self.selected_folder = QtWidgets.QFileDialog.getExistingDirectory(
@@ -903,4 +905,142 @@ class DownloadManager:
self.main_window, self.main_window,
f"已取消 - {APP_NAME}", f"已取消 - {APP_NAME}",
"\n已成功取消安装进程。\n" "\n已成功取消安装进程。\n"
) )
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

View File

@@ -321,14 +321,29 @@ class UIManager:
self.debug_submenu.addAction(self.debug_action) self.debug_submenu.addAction(self.debug_action)
self.debug_submenu.addAction(self.open_log_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 = QAction("修改下载源", self.main_window)
self.switch_source_action.setFont(menu_font) # 设置自定义字体 self.switch_source_action.setFont(menu_font)
self.switch_source_action.setEnabled(True) # 启用但显示"正在开发中" self.switch_source_action.setEnabled(True)
self.switch_source_action.triggered.connect(self.show_under_development) 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.addSeparator()
self.ui.menu.addMenu(self.dev_menu) # 添加开发者选项子菜单 self.ui.menu.addMenu(self.dev_menu) # 添加开发者选项子菜单
@@ -450,6 +465,19 @@ class UIManager:
) )
msg_box.exec() 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): def open_log_file(self):
"""打开log.txt文件""" """打开log.txt文件"""
if os.path.exists(LOG_FILE): if os.path.exists(LOG_FILE):

View File

@@ -63,4 +63,16 @@ GAME_INFO = app_data["game_info"]
BLOCK_SIZE = 67108864 BLOCK_SIZE = 67108864
HASH_SIZE = 134217728 HASH_SIZE = 134217728
PLUGIN_HASH = {game: info["hash"] for game, info in GAME_INFO.items()} PLUGIN_HASH = {game: info["hash"] for game, info in GAME_INFO.items()}
PROCESS_INFO = {info["exe"]: game for game, info in GAME_INFO.items()} 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"

View File

@@ -1,5 +1,6 @@
import os import os
import sys import sys
import subprocess
import shutil import shutil
import json import json
import webbrowser import webbrowser
@@ -13,7 +14,8 @@ from PySide6.QtGui import QAction # Added for menu actions
from ui.Ui_install import Ui_MainWindows from ui.Ui_install import Ui_MainWindows
from data.config import ( from data.config import (
APP_NAME, PLUGIN, GAME_INFO, BLOCK_SIZE, 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 ( from utils import (
load_config, save_config, HashManager, AdminPrivileges, msgbox_frame, load_image_from_file load_config, save_config, HashManager, AdminPrivileges, msgbox_frame, load_image_from_file
@@ -72,6 +74,10 @@ class MainWindow(QMainWindow):
# 初始化下载管理器 - 应该放在其他管理器之后,因为它可能依赖于它们 # 初始化下载管理器 - 应该放在其他管理器之后,因为它可能依赖于它们
self.download_manager = DownloadManager(self) 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.cloud_config = None
self.config_valid = False # 添加配置有效标志 self.config_valid = False # 添加配置有效标志
@@ -159,6 +165,11 @@ class MainWindow(QMainWindow):
"""动画完成后启用按钮""" """动画完成后启用按钮"""
self.animation_in_progress = False 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: if self.config_valid:
self.set_start_button_enabled(True) self.set_start_button_enabled(True)
@@ -246,12 +257,13 @@ class MainWindow(QMainWindow):
Args: Args:
url: 下载URL url: 下载URL
_7z_path: 7z文件保存路径 _7z_path: 7z文件保存路径
game_version: 游戏版本 game_version: 游戏版本名称
Returns: Returns:
DownloadThread: 下载线程实例 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): def create_progress_window(self):
"""创建下载进度窗口 """创建下载进度窗口

View File

@@ -154,6 +154,12 @@ class DownloadThread(QThread):
aria2c_path, aria2c_path,
] ]
# 获取主窗口的下载管理器对象
thread_count = 64 # 默认值
if hasattr(self.parent(), 'download_manager'):
# 从下载管理器获取线程数设置
thread_count = self.parent().download_manager.get_download_thread_count()
# 将所有的优化参数应用于每个下载任务 # 将所有的优化参数应用于每个下载任务
command.extend([ command.extend([
'--dir', download_dir, '--dir', download_dir,
@@ -181,7 +187,7 @@ class DownloadThread(QThread):
'--auto-file-renaming=false', '--auto-file-renaming=false',
'--allow-overwrite=true', '--allow-overwrite=true',
'--split=128', '--split=128',
'--max-connection-per-server=64', f'--max-connection-per-server={thread_count}', # 使用动态的线程数
'--min-split-size=1M', # 减小最小分片大小 '--min-split-size=1M', # 减小最小分片大小
'--optimize-concurrent-downloads=true', # 优化并发下载 '--optimize-concurrent-downloads=true', # 优化并发下载
'--file-allocation=none', # 禁用文件预分配加快开始 '--file-allocation=none', # 禁用文件预分配加快开始