feat(core): 添加卸载补丁功能并优化用户界面

- 在主界面添加卸载补丁按钮,实现卸载功能
- 优化菜单区域,使用按钮替代传统菜单栏
- 更新主题颜色,调整按钮布局和样式
- 优化帮助和设置菜单,提升用户体验
This commit is contained in:
hyb-oyqq
2025-07-25 17:00:55 +08:00
parent 286270a819
commit 38549e098e
4 changed files with 386 additions and 129 deletions

View File

@@ -49,6 +49,7 @@ class MultiStageAnimations(QObject):
# 移除菜单背景动画 # 移除菜单背景动画
# {"widget": ui.menubg, "end_pos": QPoint(720, 55), "duration": 600}, # {"widget": ui.menubg, "end_pos": QPoint(720, 55), "duration": 600},
{"widget": ui.button_container, "end_pos": None, "duration": 600}, {"widget": ui.button_container, "end_pos": None, "duration": 600},
{"widget": ui.uninstall_container, "end_pos": None, "duration": 600}, # 添加卸载补丁按钮
{"widget": ui.exit_container, "end_pos": None, "duration": 600} {"widget": ui.exit_container, "end_pos": None, "duration": 600}
] ]
@@ -68,6 +69,14 @@ class MultiStageAnimations(QObject):
lambda: self.end_button_click_animation(self.ui.button_container) lambda: self.end_button_click_animation(self.ui.button_container)
) )
# 为卸载补丁按钮添加点击动画
self.ui.uninstall_btn.pressed.connect(
lambda: self.start_button_click_animation(self.ui.uninstall_container)
)
self.ui.uninstall_btn.released.connect(
lambda: self.end_button_click_animation(self.ui.uninstall_container)
)
# 为退出按钮添加点击动画 # 为退出按钮添加点击动画
self.ui.exit_btn.pressed.connect( self.ui.exit_btn.pressed.connect(
lambda: self.start_button_click_animation(self.ui.exit_container) lambda: self.start_button_click_animation(self.ui.exit_container)
@@ -240,6 +249,9 @@ class MultiStageAnimations(QObject):
# 更新按钮最终位置 # 更新按钮最终位置
self._update_button_positions() self._update_button_positions()
# 跟踪最后一个动画用于连接finished信号
last_anim = None
for item in self.menu_widgets: for item in self.menu_widgets:
anim_group = QParallelAnimationGroup() anim_group = QParallelAnimationGroup()
@@ -259,12 +271,17 @@ class MultiStageAnimations(QObject):
anim_group.addAnimation(pos_anim) anim_group.addAnimation(pos_anim)
anim_group.addAnimation(opacity_anim) anim_group.addAnimation(opacity_anim)
# 记录最后一个按钮的动画
if item["widget"] == self.ui.exit_container: if item["widget"] == self.ui.exit_container:
anim_group.finished.connect(self.animation_finished.emit) last_anim = anim_group
anim_group.start() anim_group.start()
self.animations.append(anim_group) self.animations.append(anim_group)
# 在最后一个动画完成时发出信号
if last_anim:
last_anim.finished.connect(self.animation_finished.emit)
def _update_button_positions(self): def _update_button_positions(self):
"""更新按钮最终位置""" """更新按钮最终位置"""
# 根据当前窗口大小动态计算按钮位置 # 根据当前窗口大小动态计算按钮位置
@@ -279,18 +296,29 @@ class MultiStageAnimations(QObject):
if hasattr(self.ui, 'button_container'): if hasattr(self.ui, 'button_container'):
btn_width = self.ui.button_container.width() btn_width = self.ui.button_container.width()
x_pos = width - btn_width - right_margin x_pos = width - btn_width - right_margin
y_pos = int((height - 55) * 0.42) - 10 # 调整Y位置以适应扩大的容器 y_pos = int((height - 65) * 0.28) - 10 # 与resizeEvent中保持一致
# 更新动画目标位置 # 更新动画目标位置
for item in self.menu_widgets: for item in self.menu_widgets:
if item["widget"] == self.ui.button_container: if item["widget"] == self.ui.button_container:
item["end_pos"] = QPoint(x_pos, y_pos) item["end_pos"] = QPoint(x_pos, y_pos)
# 卸载补丁按钮
if hasattr(self.ui, 'uninstall_container'):
btn_width = self.ui.uninstall_container.width()
x_pos = width - btn_width - right_margin
y_pos = int((height - 65) * 0.46) - 10 # 与resizeEvent中保持一致
# 更新动画目标位置
for item in self.menu_widgets:
if item["widget"] == self.ui.uninstall_container:
item["end_pos"] = QPoint(x_pos, y_pos)
# 退出按钮 # 退出按钮
if hasattr(self.ui, 'exit_container'): if hasattr(self.ui, 'exit_container'):
btn_width = self.ui.exit_container.width() btn_width = self.ui.exit_container.width()
x_pos = width - btn_width - right_margin x_pos = width - btn_width - right_margin
y_pos = int((height - 55) * 0.62) - 10 # 调整Y位置以适应扩大的容器 y_pos = int((height - 65) * 0.64) - 10 # 与resizeEvent中保持一致
# 更新动画目标位置 # 更新动画目标位置
for item in self.menu_widgets: for item in self.menu_widgets:
@@ -300,9 +328,11 @@ class MultiStageAnimations(QObject):
# 默认位置 # 默认位置
for item in self.menu_widgets: for item in self.menu_widgets:
if item["widget"] == self.ui.button_container: if item["widget"] == self.ui.button_container:
item["end_pos"] = QPoint(1050, 285) item["end_pos"] = QPoint(1050, 200)
elif item["widget"] == self.ui.uninstall_container:
item["end_pos"] = QPoint(1050, 310)
elif item["widget"] == self.ui.exit_container: elif item["widget"] == self.ui.exit_container:
item["end_pos"] = QPoint(1050, 415) item["end_pos"] = QPoint(1050, 420)
def start_animations(self): def start_animations(self):
"""启动完整动画序列""" """启动完整动画序列"""

View File

@@ -1,4 +1,4 @@
from PySide6.QtGui import QIcon, QAction from PySide6.QtGui import QIcon, QAction, QFont
from PySide6.QtWidgets import QMessageBox, QMainWindow from PySide6.QtWidgets import QMessageBox, QMainWindow
from PySide6.QtCore import Qt from PySide6.QtCore import Qt
import webbrowser import webbrowser
@@ -39,20 +39,28 @@ class UIManager:
if not self.ui or not hasattr(self.ui, 'menu_2'): if not self.ui or not hasattr(self.ui, 'menu_2'):
return return
# 创建菜单项
project_home_action = QAction("项目主页", self.main_window) project_home_action = QAction("项目主页", self.main_window)
project_home_action.triggered.connect(self.open_project_home_page) project_home_action.triggered.connect(self.open_project_home_page)
about_action = QAction("关于", self.main_window) about_action = QAction("关于", self.main_window)
about_action.triggered.connect(self.show_about_dialog) about_action.triggered.connect(self.show_about_dialog)
# 添加到菜单
self.ui.menu_2.addAction(project_home_action) self.ui.menu_2.addAction(project_home_action)
self.ui.menu_2.addAction(about_action) self.ui.menu_2.addAction(about_action)
# 连接按钮点击事件,如果使用按钮式菜单
if hasattr(self.ui, 'help_btn'):
# 按钮已经连接到显示菜单,不需要额外处理
pass
def _setup_settings_menu(self): def _setup_settings_menu(self):
"""设置"设置"菜单""" """设置"设置"菜单"""
if not self.ui or not hasattr(self.ui, 'menu'): if not self.ui or not hasattr(self.ui, 'menu'):
return return
# 创建菜单项
self.debug_action = QAction("Debug模式", self.main_window, checkable=True) self.debug_action = QAction("Debug模式", self.main_window, checkable=True)
# 安全地获取config属性 # 安全地获取config属性
@@ -67,6 +75,7 @@ class UIManager:
if hasattr(self.main_window, 'toggle_debug_mode'): if hasattr(self.main_window, 'toggle_debug_mode'):
self.debug_action.triggered.connect(self.main_window.toggle_debug_mode) self.debug_action.triggered.connect(self.main_window.toggle_debug_mode)
# 添加到菜单
self.ui.menu.addAction(self.debug_action) self.ui.menu.addAction(self.debug_action)
# 为未来功能预留的"切换下载源"按钮 # 为未来功能预留的"切换下载源"按钮
@@ -74,6 +83,14 @@ class UIManager:
self.switch_source_action.setEnabled(False) # 暂时禁用 self.switch_source_action.setEnabled(False) # 暂时禁用
self.ui.menu.addAction(self.switch_source_action) self.ui.menu.addAction(self.switch_source_action)
# 添加分隔符
self.ui.menu.addSeparator()
# 连接按钮点击事件,如果使用按钮式菜单
if hasattr(self.ui, 'settings_btn'):
# 按钮已经连接到显示菜单,不需要额外处理
pass
def open_project_home_page(self): def open_project_home_page(self):
"""打开项目主页""" """打开项目主页"""
webbrowser.open("https://github.com/hyb-oyqq/FRAISEMOE-Addons-Installer-NEXT") webbrowser.open("https://github.com/hyb-oyqq/FRAISEMOE-Addons-Installer-NEXT")

View File

@@ -8,6 +8,7 @@ from PySide6 import QtWidgets
from PySide6.QtCore import QTimer, Qt, QPoint, QRect, QSize from PySide6.QtCore import QTimer, Qt, QPoint, QRect, QSize
from PySide6.QtWidgets import QMainWindow, QMessageBox, QGraphicsOpacityEffect, QGraphicsColorizeEffect from PySide6.QtWidgets import QMainWindow, QMessageBox, QGraphicsOpacityEffect, QGraphicsColorizeEffect
from PySide6.QtGui import QPalette, QColor, QPainterPath, QRegion from PySide6.QtGui import QPalette, QColor, QPainterPath, QRegion
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 (
@@ -107,6 +108,7 @@ class MainWindow(QMainWindow):
# 连接信号 - 绑定到新按钮 # 连接信号 - 绑定到新按钮
self.ui.start_install_btn.clicked.connect(self.handle_install_button_click) self.ui.start_install_btn.clicked.connect(self.handle_install_button_click)
self.ui.uninstall_btn.clicked.connect(self.handle_uninstall_button_click) # 添加卸载补丁按钮事件连接
self.ui.exit_btn.clicked.connect(self.shutdown_app) self.ui.exit_btn.clicked.connect(self.shutdown_app)
# 初始化按钮状态标记 # 初始化按钮状态标记
@@ -178,14 +180,14 @@ class MainWindow(QMainWindow):
# 更新内容区域大小 # 更新内容区域大小
if hasattr(self.ui, 'inner_content'): if hasattr(self.ui, 'inner_content'):
self.ui.inner_content.setGeometry(0, 55, new_width, new_height - 55) self.ui.inner_content.setGeometry(0, 65, new_width, new_height - 65)
# 更新背景图大小 # 更新背景图大小
if hasattr(self.ui, 'Mainbg'): if hasattr(self.ui, 'Mainbg'):
self.ui.Mainbg.setGeometry(0, 0, new_width, new_height - 55) self.ui.Mainbg.setGeometry(0, 0, new_width, new_height - 65)
if hasattr(self.ui, 'loadbg'): if hasattr(self.ui, 'loadbg'):
self.ui.loadbg.setGeometry(0, 0, new_width, new_height - 55) self.ui.loadbg.setGeometry(0, 0, new_width, new_height - 65)
# 调整按钮位置 - 固定在右侧 # 调整按钮位置 - 固定在右侧
right_margin = 20 # 减小右边距,使按钮更靠右 right_margin = 20 # 减小右边距,使按钮更靠右
@@ -193,14 +195,22 @@ class MainWindow(QMainWindow):
btn_width = 211 # 扩大后的容器宽度 btn_width = 211 # 扩大后的容器宽度
btn_height = 111 # 扩大后的容器高度 btn_height = 111 # 扩大后的容器高度
x_pos = new_width - btn_width - right_margin x_pos = new_width - btn_width - right_margin
y_pos = int((new_height - 55) * 0.42) - 10 # 调整Y位置以适应扩大的容器 y_pos = int((new_height - 65) * 0.28) - 10 # 调整为更靠上的位置
self.ui.button_container.setGeometry(x_pos, y_pos, btn_width, btn_height) self.ui.button_container.setGeometry(x_pos, y_pos, btn_width, btn_height)
# 添加卸载补丁按钮容器的位置调整
if hasattr(self.ui, 'uninstall_container'):
btn_width = 211 # 扩大后的容器宽度
btn_height = 111 # 扩大后的容器高度
x_pos = new_width - btn_width - right_margin
y_pos = int((new_height - 65) * 0.46) - 10 # 调整为中间位置
self.ui.uninstall_container.setGeometry(x_pos, y_pos, btn_width, btn_height)
if hasattr(self.ui, 'exit_container'): if hasattr(self.ui, 'exit_container'):
btn_width = 211 # 扩大后的容器宽度 btn_width = 211 # 扩大后的容器宽度
btn_height = 111 # 扩大后的容器高度 btn_height = 111 # 扩大后的容器高度
x_pos = new_width - btn_width - right_margin x_pos = new_width - btn_width - right_margin
y_pos = int((new_height - 55) * 0.62) - 10 # 调整Y位置以适应扩大的容器 y_pos = int((new_height - 65) * 0.64) - 10 # 调整为更靠下的位置
self.ui.exit_container.setGeometry(x_pos, y_pos, btn_width, btn_height) self.ui.exit_container.setGeometry(x_pos, y_pos, btn_width, btn_height)
# 更新圆角 # 更新圆角
@@ -590,4 +600,169 @@ class MainWindow(QMainWindow):
# 按钮处于"开始安装"状态,正常执行安装流程 # 按钮处于"开始安装"状态,正常执行安装流程
self.download_manager.file_dialog() self.download_manager.file_dialog()
def handle_uninstall_button_click(self):
"""处理卸载补丁按钮点击事件
打开文件选择对话框选择游戏目录,然后卸载对应游戏的补丁
"""
# 获取游戏目录
from PySide6.QtWidgets import QFileDialog
# 打开文件选择对话框
game_dir = QFileDialog.getExistingDirectory(
self,
"选择游戏目录",
""
)
if not game_dir or game_dir == "":
return # 用户取消了选择
# 验证所选目录是否为有效的游戏目录
game_version = self.identify_game_version(game_dir)
if not game_version:
msg_box = msgbox_frame(
f"错误 - {APP_NAME}",
"\n所选目录不是有效的NEKOPARA游戏目录。\n请选择包含游戏可执行文件的目录。\n",
QMessageBox.StandardButton.Ok,
)
msg_box.exec()
return
# 确认卸载
reply = QMessageBox.question(
self,
f"确认卸载 - {APP_NAME}",
f"\n确定要卸载 {game_version} 的补丁吗?\n",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
QMessageBox.StandardButton.No
)
if reply == QMessageBox.StandardButton.No:
return
# 开始卸载补丁
self.uninstall_patch(game_dir, game_version)
def identify_game_version(self, game_dir):
"""识别游戏版本
Args:
game_dir: 游戏目录路径
Returns:
str: 游戏版本名称如果不是有效的游戏目录则返回None
"""
import os
# 检查是否为NEKOPARA游戏目录
# 通过检查游戏可执行文件来识别游戏版本
for game_version, info in GAME_INFO.items():
exe_path = os.path.join(game_dir, info["exe"])
if os.path.exists(exe_path):
return game_version
# 如果没有直接匹配,尝试通过目录名称推断
dir_name = os.path.basename(game_dir).lower()
if "vol" in dir_name or "vol." in dir_name:
# 尝试提取卷号
if "vol 1" in dir_name or "vol.1" in dir_name or "vol1" in dir_name:
return "NEKOPARA Vol.1"
elif "vol 2" in dir_name or "vol.2" in dir_name or "vol2" in dir_name:
return "NEKOPARA Vol.2"
elif "vol 3" in dir_name or "vol.3" in dir_name or "vol3" in dir_name:
return "NEKOPARA Vol.3"
elif "vol 4" in dir_name or "vol.4" in dir_name or "vol4" in dir_name:
return "NEKOPARA Vol.4"
elif "after" in dir_name:
return "NEKOPARA After"
return None
def uninstall_patch(self, game_dir, game_version):
"""卸载补丁
Args:
game_dir: 游戏目录路径
game_version: 游戏版本
"""
import os
import shutil
if game_version not in GAME_INFO:
QMessageBox.critical(
self,
f"错误 - {APP_NAME}",
f"\n无法识别游戏版本: {game_version}\n",
QMessageBox.StandardButton.Ok,
)
return
try:
# 获取补丁文件路径
patch_file_path = os.path.join(game_dir, os.path.basename(GAME_INFO[game_version]["install_path"]))
# 检查补丁文件是否存在
if os.path.exists(patch_file_path):
os.remove(patch_file_path)
print(f"已删除补丁文件: {patch_file_path}")
# 检查是否有额外的签名文件 (.sig)
if game_version == "NEKOPARA After":
sig_file_path = f"{patch_file_path}.sig"
if os.path.exists(sig_file_path):
os.remove(sig_file_path)
print(f"已删除签名文件: {sig_file_path}")
# 删除patch文件夹
patch_folder = os.path.join(game_dir, "patch")
if os.path.exists(patch_folder):
shutil.rmtree(patch_folder)
print(f"已删除补丁文件夹: {patch_folder}")
# 删除game/patch文件夹
game_patch_folder = os.path.join(game_dir, "game", "patch")
if os.path.exists(game_patch_folder):
shutil.rmtree(game_patch_folder)
print(f"已删除game/patch文件夹: {game_patch_folder}")
# 删除配置文件
config_file = os.path.join(game_dir, "game", "config.json")
if os.path.exists(config_file):
os.remove(config_file)
print(f"已删除配置文件: {config_file}")
scripts_file = os.path.join(game_dir, "game", "scripts.json")
if os.path.exists(scripts_file):
os.remove(scripts_file)
print(f"已删除脚本文件: {scripts_file}")
# 更新安装状态
self.installed_status[game_version] = False
# 显示卸载成功消息
QMessageBox.information(
self,
f"卸载完成 - {APP_NAME}",
f"\n{game_version} 补丁卸载成功!\n",
QMessageBox.StandardButton.Ok,
)
else:
QMessageBox.warning(
self,
f"警告 - {APP_NAME}",
f"\n未找到 {game_version} 的补丁文件,可能未安装补丁或已被移除。\n",
QMessageBox.StandardButton.Ok,
)
except Exception as e:
# 显示卸载失败消息
QMessageBox.critical(
self,
f"卸载失败 - {APP_NAME}",
f"\n卸载 {game_version} 补丁时出错:\n\n{str(e)}\n",
QMessageBox.StandardButton.Ok,
)

View File

@@ -13,6 +13,9 @@ from PySide6.QtWidgets import (QApplication, QLabel, QMainWindow, QMenu,
QMenuBar, QPushButton, QSizePolicy, QWidget, QHBoxLayout) QMenuBar, QPushButton, QSizePolicy, QWidget, QHBoxLayout)
import os import os
# 导入配置常量
from data.config import APP_NAME, APP_VERSION
def load_base64_image(base64_str): def load_base64_image(base64_str):
pixmap = QPixmap() pixmap = QPixmap()
pixmap.loadFromData(base64.b64decode(base64_str)) pixmap.loadFromData(base64.b64decode(base64_str))
@@ -63,9 +66,9 @@ class Ui_MainWindows(object):
self.main_container.setGeometry(QRect(0, 0, 1280, 720)) self.main_container.setGeometry(QRect(0, 0, 1280, 720))
self.main_container.setStyleSheet(""" self.main_container.setStyleSheet("""
QWidget#main_container { QWidget#main_container {
background-color: #C5DDFC; background-color: #E96948;
border-radius: 20px; border-radius: 20px;
border: 1px solid #A4C2F4; border: 1px solid #E96948;
} }
""") """)
@@ -87,22 +90,16 @@ class Ui_MainWindows(object):
region = QRegion(path.toFillPolygon().toPolygon()) region = QRegion(path.toFillPolygon().toPolygon())
self.content_container.setMask(region) self.content_container.setMask(region)
# 禁用裁剪,这可能导致窗口变形
# rect = self.content_container.rect()
# path = QPainterPath()
# path.addRoundedRect(rect, 20, 20)
# self.content_container.setMask(QRegion(path.toFillPolygon().toPolygon()))
# 标题栏 # 标题栏
self.title_bar = QWidget(self.content_container) self.title_bar = QWidget(self.content_container)
self.title_bar.setObjectName(u"title_bar") self.title_bar.setObjectName(u"title_bar")
self.title_bar.setGeometry(QRect(0, 0, 1280, 30)) self.title_bar.setGeometry(QRect(0, 0, 1280, 35)) # 减小高度从40到35
self.title_bar.setStyleSheet(""" self.title_bar.setStyleSheet("""
QWidget#title_bar { QWidget#title_bar {
background-color: #A4C2F4; background-color: #E96948;
border-top-left-radius: 20px; border-top-left-radius: 20px;
border-top-right-radius: 20px; border-top-right-radius: 20px;
border-bottom: 1px solid #8AB4F8; border-bottom: 1px solid #F47A5B;
} }
""") """)
@@ -159,8 +156,9 @@ class Ui_MainWindows(object):
# 标题文本 # 标题文本
self.title_label = QLabel(self.title_bar) self.title_label = QLabel(self.title_bar)
self.title_label.setObjectName(u"title_label") self.title_label.setObjectName(u"title_label")
self.title_label.setText("FraiseMoe Addons Manager") # 直接使用APP_NAME并添加版本号
title_font = QFont(font_family, 12) self.title_label.setText(f"{APP_NAME} v{APP_VERSION}")
title_font = QFont(font_family, 14) # 减小字体从16到14
title_font.setBold(True) title_font.setBold(True)
self.title_label.setFont(title_font) self.title_label.setFont(title_font)
self.title_label.setStyleSheet("color: #333333; padding-left: 10px;") self.title_label.setStyleSheet("color: #333333; padding-left: 10px;")
@@ -173,61 +171,111 @@ class Ui_MainWindows(object):
self.title_layout.addSpacing(5) self.title_layout.addSpacing(5)
self.title_layout.addWidget(self.close_btn) self.title_layout.addWidget(self.close_btn)
# 菜单区域 # 修改菜单区域 - 确保足够宽以容纳更多菜单项
self.menu_area = QWidget(self.content_container) self.menu_area = QWidget(self.content_container)
self.menu_area.setObjectName(u"menu_area") self.menu_area.setObjectName(u"menu_area")
self.menu_area.setGeometry(QRect(0, 30, 1024, 25)) self.menu_area.setGeometry(QRect(0, 35, 1280, 30)) # 调整位置从40到35高度从35到30
self.menu_area.setStyleSheet(""" self.menu_area.setStyleSheet("""
QWidget#menu_area { QWidget#menu_area {
background-color: #D4E4FC; background-color: #E96948;
border-bottom: 1px solid #A4C2F4;
} }
""") """)
# 创建菜单栏在菜单区域中 # 不再使用菜单栏,改用普通按钮
self.menubar = QMenuBar(self.menu_area) # 创建菜单按钮字体
self.menubar.setObjectName(u"menubar") menu_font = QFont(font_family, 14) # 进一步减小字体大小到14
self.menubar.setGeometry(QRect(10, 2, 200, 20)) menu_font.setBold(True)
self.menubar.setStyleSheet("""
QMenuBar { # 设置按钮
self.settings_btn = QPushButton("设置", self.menu_area)
self.settings_btn.setObjectName(u"settings_btn")
self.settings_btn.setGeometry(QRect(20, 1, 80, 28)) # 调整高度和Y位置
self.settings_btn.setFont(menu_font)
self.settings_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
self.settings_btn.setStyleSheet("""
QPushButton {
background-color: transparent; background-color: transparent;
color: #333333; color: white;
font-weight: bold; border: none;
spacing: 5px; text-align: left;
padding-left: 10px;
} }
QMenuBar::item { QPushButton:hover {
background-color: transparent; background-color: #F47A5B;
padding: 1px 8px;
border-radius: 4px; border-radius: 4px;
} }
QMenuBar::item:selected { QPushButton:pressed {
background-color: rgba(0, 0, 0, 0.1); background-color: #D25A3C;
}
QMenuBar::item:pressed {
background-color: rgba(0, 0, 0, 0.15);
}
QMenu {
background-color: #D4E4FC;
border: 1px solid #A4C2F4;
border-radius: 6px;
padding: 5px;
margin: 2px;
}
QMenu::item {
padding: 6px 25px 6px 20px;
color: #333333;
border-radius: 4px; border-radius: 4px;
} }
QMenu::item:selected {
background-color: rgba(0, 0, 0, 0.1);
}
""") """)
# 帮助按钮
self.help_btn = QPushButton("帮助", self.menu_area)
self.help_btn.setObjectName(u"help_btn")
self.help_btn.setGeometry(QRect(120, 1, 80, 28)) # 调整高度和Y位置
self.help_btn.setFont(menu_font)
self.help_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
self.help_btn.setStyleSheet(self.settings_btn.styleSheet())
# 将原来的菜单项移到全局,方便访问
self.menu = QMenu(self.content_container)
self.menu.setObjectName(u"menu")
self.menu.setTitle("设置")
self.menu.setFont(menu_font)
self.menu.setStyleSheet("""
QMenu {
background-color: #E96948;
color: white;
font-size: 16px;
font-weight: bold;
border: 1px solid #F47A5B;
padding: 8px;
border-radius: 6px;
margin-top: 2px;
}
QMenu::item {
padding: 6px 20px 6px 15px;
background-color: transparent;
min-width: 120px;
color: white;
}
QMenu::item:selected {
background-color: #F47A5B;
border-radius: 4px;
}
QMenu::separator {
height: 1px;
background-color: #F47A5B;
margin: 5px 15px;
}
""")
self.menu_2 = QMenu(self.content_container)
self.menu_2.setObjectName(u"menu_2")
self.menu_2.setTitle("帮助")
self.menu_2.setFont(menu_font)
self.menu_2.setStyleSheet(self.menu.styleSheet())
# 连接按钮点击事件到显示对应菜单
self.settings_btn.clicked.connect(lambda: self.show_menu(self.menu, self.settings_btn))
self.help_btn.clicked.connect(lambda: self.show_menu(self.menu_2, self.help_btn))
# 预留位置给未来可能的第三个按钮
# 第三个按钮可以这样添加:
# self.third_btn = QPushButton("第三项", self.menu_area)
# self.third_btn.setObjectName(u"third_btn")
# self.third_btn.setGeometry(QRect(320, 0, 120, 35))
# self.third_btn.setFont(menu_font)
# self.third_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
# self.third_btn.setStyleSheet(self.settings_btn.styleSheet())
# self.third_btn.clicked.connect(lambda: self.show_menu(self.menu_3, self.third_btn))
# 内容子容器 # 内容子容器
self.inner_content = QWidget(self.content_container) self.inner_content = QWidget(self.content_container)
self.inner_content.setObjectName(u"inner_content") self.inner_content.setObjectName(u"inner_content")
# 确保宽度足够大,保证右侧元素完全显示 # 确保宽度足够大,保证右侧元素完全显示
self.inner_content.setGeometry(QRect(0, 55, 1280, 665)) self.inner_content.setGeometry(QRect(0, 65, 1280, 655)) # 调整Y位置从75到65高度从645到655
self.inner_content.setStyleSheet(""" self.inner_content.setStyleSheet("""
QWidget#inner_content { QWidget#inner_content {
background-color: transparent; background-color: transparent;
@@ -243,43 +291,12 @@ class Ui_MainWindows(object):
inner_region = QRegion(inner_path.toFillPolygon().toPolygon()) inner_region = QRegion(inner_path.toFillPolygon().toPolygon())
self.inner_content.setMask(inner_region) self.inner_content.setMask(inner_region)
# 确保底部的圆角正确显示
# 在菜单背景区域下方添加一个底部圆角装饰器
# self.bottom_corner_left = QWidget(self.main_container)
# self.bottom_corner_left.setObjectName(u"bottom_corner_left")
# self.bottom_corner_left.setGeometry(QRect(0, 556, 20, 20))
# self.bottom_corner_left.setStyleSheet("""
# QWidget#bottom_corner_left {
# background-color: #C5DDFC;
# border-bottom-left-radius: 20px;
# }
# """)
# self.bottom_corner_right = QWidget(self.main_container)
# self.bottom_corner_right.setObjectName(u"bottom_corner_right")
# self.bottom_corner_right.setGeometry(QRect(1004, 556, 20, 20))
# self.bottom_corner_right.setStyleSheet("""
# QWidget#bottom_corner_right {
# background-color: #C5DDFC;
# border-bottom-right-radius: 20px;
# }
# """)
self.menu = QMenu(self.menubar)
self.menu.setObjectName(u"menu")
self.menu_2 = QMenu(self.menubar)
self.menu_2.setObjectName(u"menu_2")
self.menubar.addAction(self.menu.menuAction())
self.menubar.addAction(self.menu_2.menuAction())
self.menu.addSeparator()
# 在主容器中添加背景和内容元素 # 在主容器中添加背景和内容元素
# 修改loadbg使用title_bg1.png作为整个背景 # 修改loadbg使用title_bg1.png作为整个背景
# 原来的loadbg保持不变 # 原来的loadbg保持不变
self.loadbg = QLabel(self.inner_content) self.loadbg = QLabel(self.inner_content)
self.loadbg.setObjectName(u"loadbg") self.loadbg.setObjectName(u"loadbg")
self.loadbg.setGeometry(QRect(0, 0, 1280, 665)) # 调整尺寸 self.loadbg.setGeometry(QRect(0, 0, 1280, 655)) # 调整高度从645到655
self.loadbg.setPixmap(load_base64_image(img_data["loadbg"])) self.loadbg.setPixmap(load_base64_image(img_data["loadbg"]))
self.loadbg.setScaledContents(True) self.loadbg.setScaledContents(True)
@@ -316,7 +333,7 @@ class Ui_MainWindows(object):
# 修复Mainbg位置并使用title_bg1.png作为背景图片 # 修复Mainbg位置并使用title_bg1.png作为背景图片
self.Mainbg = QLabel(self.inner_content) self.Mainbg = QLabel(self.inner_content)
self.Mainbg.setObjectName(u"Mainbg") self.Mainbg.setObjectName(u"Mainbg")
self.Mainbg.setGeometry(QRect(0, 0, 1280, 665)) # 调整尺寸 self.Mainbg.setGeometry(QRect(0, 0, 1280, 655)) # 调整高度从645到655
self.Mainbg.setPixmap(load_image_from_file(os.path.join(os.path.dirname(os.path.dirname(__file__)), "IMG", "BG", "title_bg1.png"))) self.Mainbg.setPixmap(load_image_from_file(os.path.join(os.path.dirname(os.path.dirname(__file__)), "IMG", "BG", "title_bg1.png")))
self.Mainbg.setScaledContents(True) self.Mainbg.setScaledContents(True)
@@ -325,9 +342,10 @@ class Ui_MainWindows(object):
# 创建文本标签布局的按钮 # 创建文本标签布局的按钮
# 开始安装按钮 - 基于背景图片和标签组合 # 开始安装按钮 - 基于背景图片和标签组合
# 调整开始安装按钮的位置
self.button_container = QWidget(self.inner_content) self.button_container = QWidget(self.inner_content)
self.button_container.setObjectName(u"start_install_container") self.button_container.setObjectName(u"start_install_container")
self.button_container.setGeometry(QRect(1050, 285, 211, 111)) # 扩大容器尺寸,预留动画空间 self.button_container.setGeometry(QRect(1050, 200, 211, 111)) # 调整Y坐标上移至200
# 不要隐藏容器,让动画系统来控制它的可见性和位置 # 不要隐藏容器,让动画系统来控制它的可见性和位置
# 使用原来的按钮背景图片 # 使用原来的按钮背景图片
@@ -359,10 +377,44 @@ class Ui_MainWindows(object):
} }
""") """)
# 退出按钮 - 基于背景图片和标签组合 # 添加卸载补丁按钮 - 新增
self.uninstall_container = QWidget(self.inner_content)
self.uninstall_container.setObjectName(u"uninstall_container")
self.uninstall_container.setGeometry(QRect(1050, 310, 211, 111)) # 调整Y坐标位于310位置
# 使用相同的按钮背景图片
self.uninstall_bg = QLabel(self.uninstall_container)
self.uninstall_bg.setObjectName(u"uninstall_bg")
self.uninstall_bg.setGeometry(QRect(10, 10, 191, 91)) # 居中放置在扩大的容器中
self.uninstall_bg.setPixmap(button_pixmap)
self.uninstall_bg.setScaledContents(True)
self.uninstall_text = QLabel(self.uninstall_container)
self.uninstall_text.setObjectName(u"uninstall_text")
self.uninstall_text.setGeometry(QRect(10, 7, 191, 91)) # 居中放置在扩大的容器中
self.uninstall_text.setText("卸载补丁")
self.uninstall_text.setFont(self.custom_font)
self.uninstall_text.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.uninstall_text.setStyleSheet("letter-spacing: 1px;")
# 点击区域透明按钮
self.uninstall_btn = QPushButton(self.uninstall_container)
self.uninstall_btn.setObjectName(u"uninstall_btn")
self.uninstall_btn.setGeometry(QRect(10, 10, 191, 91)) # 居中放置在扩大的容器中
self.uninstall_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) # 设置鼠标悬停时为手形光标
self.uninstall_btn.setFlat(True)
self.uninstall_btn.raise_() # 确保按钮在最上层
self.uninstall_btn.setStyleSheet("""
QPushButton {
background-color: transparent;
border: none;
}
""")
# 退出按钮 - 基于背景图片和标签组合,调整位置
self.exit_container = QWidget(self.inner_content) self.exit_container = QWidget(self.inner_content)
self.exit_container.setObjectName(u"exit_container") self.exit_container.setObjectName(u"exit_container")
self.exit_container.setGeometry(QRect(1050, 415, 211, 111)) # 扩大容器尺寸,预留动画空间 self.exit_container.setGeometry(QRect(1050, 420, 211, 111)) # 调整Y坐标下移至420
# 不要隐藏容器,让动画系统来控制它的可见性和位置 # 不要隐藏容器,让动画系统来控制它的可见性和位置
# 使用原来的按钮背景图片 # 使用原来的按钮背景图片
@@ -394,19 +446,6 @@ class Ui_MainWindows(object):
} }
""") """)
# 注释掉menubg移除右侧背景区域
# self.menubg = QLabel(self.inner_content)
# self.menubg.setObjectName(u"menubg")
# # 将X坐标调整为720以使背景图片更靠右
# self.menubg.setGeometry(QRect(720, 0, 321, 521))
# self.menubg.setPixmap(load_base64_image(img_data["menubg"]))
# self.menubg.setScaledContents(True)
# 恢复按钮位置
# self.exit_container = QWidget(self.inner_content)
# self.exit_container.setObjectName(u"exit_container")
# self.exit_container.setGeometry(QRect(780, 340, 191, 91)) # 恢复到原来的位置 780
MainWindows.setCentralWidget(self.centralwidget) MainWindows.setCentralWidget(self.centralwidget)
# 调整层级顺序 # 调整层级顺序
@@ -417,36 +456,22 @@ class Ui_MainWindows(object):
self.vol4bg.raise_() self.vol4bg.raise_()
self.afterbg.raise_() self.afterbg.raise_()
self.Mainbg.raise_() self.Mainbg.raise_()
# self.menubg.raise_() # 注释掉menubg
# 不再需要底部圆角装饰器
# self.bottom_corner_left.raise_()
# self.bottom_corner_right.raise_()
self.button_container.raise_() self.button_container.raise_()
self.uninstall_container.raise_() # 添加新按钮到层级顺序
self.exit_container.raise_() self.exit_container.raise_()
self.menu_area.raise_() # 确保菜单区域在背景之上 self.menu_area.raise_() # 确保菜单区域在背景之上
# self.menubar.raise_() # 不再需要菜单栏
self.settings_btn.raise_() # 确保设置按钮在上层
self.help_btn.raise_() # 确保帮助按钮在上层
self.title_bar.raise_() # 确保标题栏在最上层 self.title_bar.raise_() # 确保标题栏在最上层
# 保留原有菜单栏,调整到主容器内部
# self.menubar = QMenuBar(self.main_container)
# self.menubar.setObjectName(u"menubar")
# self.menubar.setGeometry(QRect(0, 0, 1024, 21))
# self.menu = QMenu(self.menubar)
# self.menu.setObjectName(u"menu")
# self.menu_2 = QMenu(self.menubar)
# self.menu_2.setObjectName(u"menu_2")
# 不再调用MainWindows.setMenuBar而是手动将菜单栏添加到主容器
# MainWindows.setMenuBar(self.menubar)
# self.menubar.addAction(self.menu.menuAction())
# self.menubar.addAction(self.menu_2.menuAction())
# self.menu.addSeparator()
self.retranslateUi(MainWindows) self.retranslateUi(MainWindows)
QMetaObject.connectSlotsByName(MainWindows) QMetaObject.connectSlotsByName(MainWindows)
# setupUi # setupUi
def retranslateUi(self, MainWindows): def retranslateUi(self, MainWindows):
MainWindows.setWindowTitle(QCoreApplication.translate("MainWindows", u" UI Test", None)) MainWindows.setWindowTitle(QCoreApplication.translate("MainWindows", f"{APP_NAME} v{APP_VERSION}", None))
self.loadbg.setText("") self.loadbg.setText("")
self.vol1bg.setText("") self.vol1bg.setText("")
self.vol2bg.setText("") self.vol2bg.setText("")
@@ -457,8 +482,18 @@ class Ui_MainWindows(object):
#if QT_CONFIG(accessibility) #if QT_CONFIG(accessibility)
self.start_install_btn.setAccessibleDescription("") self.start_install_btn.setAccessibleDescription("")
#endif // QT_CONFIG(accessibility) #endif // QT_CONFIG(accessibility)
# self.menubg.setText("") # 注释掉menubg self.menu.setTitle(QCoreApplication.translate("MainWindows", u"设置", None))
self.menu.setTitle(QCoreApplication.translate("MainWindows", u"\u8bbe\u7f6e", None)) self.menu_2.setTitle(QCoreApplication.translate("MainWindows", u"帮助", None))
self.menu_2.setTitle(QCoreApplication.translate("MainWindows", u"\u5e2e\u52a9", None))
# retranslateUi # retranslateUi
def show_menu(self, menu, button):
"""显示菜单
Args:
menu: 要显示的菜单
button: 触发菜单的按钮
"""
# 计算菜单显示位置
pos = button.mapToGlobal(button.rect().bottomLeft())
menu.exec(pos)