diff --git a/source/IMG/BG/title_bg1.png b/source/IMG/BG/title_bg1.png new file mode 100644 index 0000000..8b39823 Binary files /dev/null and b/source/IMG/BG/title_bg1.png differ diff --git a/source/IMG/BG/title_bg2.png b/source/IMG/BG/title_bg2.png new file mode 100644 index 0000000..8e2bd7f Binary files /dev/null and b/source/IMG/BG/title_bg2.png differ diff --git a/source/core/animations.py b/source/core/animations.py index 286672e..0604e7c 100644 --- a/source/core/animations.py +++ b/source/core/animations.py @@ -1,15 +1,24 @@ +import sys from PySide6.QtCore import (QObject, QPropertyAnimation, QParallelAnimationGroup, - QPoint, QEasingCurve, QTimer, Signal) -from PySide6.QtWidgets import QGraphicsOpacityEffect + QPoint, QEasingCurve, QTimer, Signal, QRect) +from PySide6.QtWidgets import QGraphicsOpacityEffect, QPushButton +from PySide6.QtGui import QColor class MultiStageAnimations(QObject): animation_finished = Signal() def __init__(self, ui, parent=None): super().__init__(parent) self.ui = ui - # 获取画布尺寸 - self.canvas_width = ui.centralwidget.width() - self.canvas_height = ui.centralwidget.height() + self.parent = parent # 保存父窗口引用以获取当前尺寸 + + # 获取画布尺寸 - 动态从父窗口获取 + if parent: + self.canvas_width = parent.width() + self.canvas_height = parent.height() + else: + # 默认尺寸 + self.canvas_width = 1280 + self.canvas_height = 720 # 动画时序配置 self.animation_config = { @@ -18,29 +27,132 @@ class MultiStageAnimations(QObject): }, "mainbg": { "delay_after": 500 + }, + "button_click": { + "scale_duration": 100, + "scale_min": 0.95, + "scale_max": 1.0 } } - # 第一阶段:Logo动画配置 + # 第一阶段:Logo动画配置,根据新布局调整Y坐标 self.logo_widgets = [ - {"widget": ui.vol1bg, "delay": 0, "duration": 500, "end_pos": QPoint(0, 120)}, - {"widget": ui.vol2bg, "delay": 80, "duration": 500, "end_pos": QPoint(0, 180)}, - {"widget": ui.vol3bg, "delay": 160, "duration": 500, "end_pos": QPoint(0, 240)}, - {"widget": ui.vol4bg, "delay": 240, "duration": 500, "end_pos": QPoint(0, 300)}, - {"widget": ui.afterbg, "delay": 320, "duration": 500, "end_pos": QPoint(0, 360)} + {"widget": ui.vol1bg, "delay": 0, "duration": 500, "end_pos": QPoint(0, 150)}, + {"widget": ui.vol2bg, "delay": 80, "duration": 500, "end_pos": QPoint(0, 210)}, + {"widget": ui.vol3bg, "delay": 160, "duration": 500, "end_pos": QPoint(0, 270)}, + {"widget": ui.vol4bg, "delay": 240, "duration": 500, "end_pos": QPoint(0, 330)}, + {"widget": ui.afterbg, "delay": 320, "duration": 500, "end_pos": QPoint(0, 390)} ] - # 第二阶段:菜单元素 + # 第二阶段:菜单元素,位置会在开始动画时动态计算 self.menu_widgets = [ - {"widget": ui.menubg, "end_pos": QPoint(710, 0), "duration": 600}, - {"widget": ui.button_container, "end_pos": QPoint(780, 250), "duration": 600}, - {"widget": ui.exit_container, "end_pos": QPoint(780, 340), "duration": 600} + # 移除菜单背景动画 + # {"widget": ui.menubg, "end_pos": QPoint(720, 55), "duration": 600}, + {"widget": ui.button_container, "end_pos": None, "duration": 600}, + {"widget": ui.exit_container, "end_pos": None, "duration": 600} ] self.animations = [] self.timers = [] + + # 设置按钮点击动画 + self.setup_button_click_animations() + + def setup_button_click_animations(self): + """设置按钮点击动画""" + # 为开始安装按钮添加点击动画 + self.ui.start_install_btn.pressed.connect( + lambda: self.start_button_click_animation(self.ui.button_container) + ) + self.ui.start_install_btn.released.connect( + lambda: self.end_button_click_animation(self.ui.button_container) + ) + + # 为退出按钮添加点击动画 + self.ui.exit_btn.pressed.connect( + lambda: self.start_button_click_animation(self.ui.exit_container) + ) + self.ui.exit_btn.released.connect( + lambda: self.end_button_click_animation(self.ui.exit_container) + ) + + def start_button_click_animation(self, button_container): + """开始按钮点击动画""" + # 创建缩放动画 + scale_anim = QPropertyAnimation(button_container.children()[0], b"geometry") # 只对按钮背景应用动画 + scale_anim.setDuration(self.animation_config["button_click"]["scale_duration"]) + + # 获取当前几何形状 + current_geometry = button_container.children()[0].geometry() + + # 计算缩放后的几何形状(保持中心点不变) + scale_factor = self.animation_config["button_click"]["scale_min"] + width_diff = current_geometry.width() * (1 - scale_factor) / 2 + height_diff = current_geometry.height() * (1 - scale_factor) / 2 + + new_geometry = QRect( + current_geometry.x() + width_diff, + current_geometry.y() + height_diff, + current_geometry.width() * scale_factor, + current_geometry.height() * scale_factor + ) + + scale_anim.setEndValue(new_geometry) + scale_anim.setEasingCurve(QEasingCurve.Type.OutQuad) + + # 启动动画 + scale_anim.start() + self.animations.append(scale_anim) + + # 对文本标签也应用同样的动画 + text_anim = QPropertyAnimation(button_container.children()[1], b"geometry") + text_anim.setDuration(self.animation_config["button_click"]["scale_duration"]) + text_geometry = button_container.children()[1].geometry() + + new_text_geometry = QRect( + text_geometry.x() + width_diff, + text_geometry.y() + height_diff, + text_geometry.width() * scale_factor, + text_geometry.height() * scale_factor + ) + + text_anim.setEndValue(new_text_geometry) + text_anim.setEasingCurve(QEasingCurve.Type.OutQuad) + text_anim.start() + self.animations.append(text_anim) + + def end_button_click_animation(self, button_container): + """结束按钮点击动画,恢复正常外观""" + # 创建恢复动画 - 对背景 + scale_anim = QPropertyAnimation(button_container.children()[0], b"geometry") + scale_anim.setDuration(self.animation_config["button_click"]["scale_duration"]) + + # 恢复到原始大小 (10,10,191,91) + original_geometry = QRect(10, 10, 191, 91) + scale_anim.setEndValue(original_geometry) + scale_anim.setEasingCurve(QEasingCurve.Type.OutElastic) + + # 启动动画 + scale_anim.start() + self.animations.append(scale_anim) + + # 恢复文本标签 + text_anim = QPropertyAnimation(button_container.children()[1], b"geometry") + text_anim.setDuration(self.animation_config["button_click"]["scale_duration"]) + + # 恢复文本到原始大小 (10,7,191,91) + text_anim.setEndValue(QRect(10, 7, 191, 91)) + text_anim.setEasingCurve(QEasingCurve.Type.OutElastic) + text_anim.start() + self.animations.append(text_anim) + def initialize(self): """初始化所有组件状态""" + # 更新画布尺寸 + if self.parent: + self.canvas_width = self.parent.width() + self.canvas_height = self.parent.height() + # 设置Mainbg初始状态 effect = QGraphicsOpacityEffect(self.ui.Mainbg) effect.setOpacity(0) @@ -125,6 +237,9 @@ class MultiStageAnimations(QObject): self.animations.append(main_anim) def start_menu_animations(self): """启动菜单动画(从下往上)""" + # 更新按钮最终位置 + self._update_button_positions() + for item in self.menu_widgets: anim_group = QParallelAnimationGroup() @@ -149,6 +264,46 @@ class MultiStageAnimations(QObject): anim_group.start() self.animations.append(anim_group) + + def _update_button_positions(self): + """更新按钮最终位置""" + # 根据当前窗口大小动态计算按钮位置 + if self.parent: + width = self.parent.width() + height = self.parent.height() + + # 计算按钮位置 + right_margin = 20 # 减小右边距,使按钮更靠右 + + # 开始安装按钮 + if hasattr(self.ui, 'button_container'): + btn_width = self.ui.button_container.width() + x_pos = width - btn_width - right_margin + y_pos = int((height - 55) * 0.42) - 10 # 调整Y位置以适应扩大的容器 + + # 更新动画目标位置 + for item in self.menu_widgets: + if item["widget"] == self.ui.button_container: + item["end_pos"] = QPoint(x_pos, y_pos) + + # 退出按钮 + if hasattr(self.ui, 'exit_container'): + btn_width = self.ui.exit_container.width() + x_pos = width - btn_width - right_margin + y_pos = int((height - 55) * 0.62) - 10 # 调整Y位置以适应扩大的容器 + + # 更新动画目标位置 + for item in self.menu_widgets: + if item["widget"] == self.ui.exit_container: + item["end_pos"] = QPoint(x_pos, y_pos) + else: + # 默认位置 + for item in self.menu_widgets: + if item["widget"] == self.ui.button_container: + item["end_pos"] = QPoint(1050, 285) + elif item["widget"] == self.ui.exit_container: + item["end_pos"] = QPoint(1050, 415) + def start_animations(self): """启动完整动画序列""" self.clear_animations() diff --git a/source/core/download_manager.py b/source/core/download_manager.py index 1db24e8..b71e5a5 100644 --- a/source/core/download_manager.py +++ b/source/core/download_manager.py @@ -140,7 +140,7 @@ class DownloadManager: def download_action(self): """开始下载流程""" # 禁用开始安装按钮 - self.main_window.ui.start_install_btn.setEnabled(False) + self.main_window.set_start_button_enabled(False) # 清空下载历史记录 self.main_window.download_queue_history = [] @@ -173,7 +173,7 @@ class DownloadManager: self.main_window, f"错误 - {APP_NAME}", "\n网络状态异常或服务器故障,请重试\n" ) # 重新启用开始安装按钮 - self.main_window.ui.start_install_btn.setEnabled(True) + self.main_window.set_start_button_enabled(True) return # 填充下载队列 @@ -565,6 +565,6 @@ class DownloadManager: # 重新启用退出按钮和开始安装按钮 self.main_window.ui.exit_btn.setEnabled(True) - self.main_window.ui.start_install_btn.setEnabled(True) + self.main_window.set_start_button_enabled(True) self.main_window.show_result() \ No newline at end of file diff --git a/source/main_window.py b/source/main_window.py index 2c2d684..5730b70 100644 --- a/source/main_window.py +++ b/source/main_window.py @@ -5,8 +5,9 @@ import json import webbrowser from PySide6 import QtWidgets -from PySide6.QtCore import QTimer -from PySide6.QtWidgets import QMainWindow, QMessageBox +from PySide6.QtCore import QTimer, Qt, QPoint, QRect, QSize +from PySide6.QtWidgets import QMainWindow, QMessageBox, QGraphicsOpacityEffect, QGraphicsColorizeEffect +from PySide6.QtGui import QPalette, QColor, QPainterPath, QRegion from ui.Ui_install import Ui_MainWindows from data.config import ( @@ -28,10 +29,31 @@ class MainWindow(QMainWindow): def __init__(self): super().__init__() + # 设置窗口为无边框 + self.setWindowFlags(Qt.WindowType.FramelessWindowHint) + # 设置窗口背景透明 + self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) + + # 调整窗口大小以适应背景图片比例 (1280x720) + self.resize(1280, 720) + # 移除大小限制,允许自由缩放 + # self.setMinimumSize(QSize(1024, 576)) + # self.setMaximumSize(QSize(1024, 576)) + + # 窗口比例 (16:9) + self.aspect_ratio = 16 / 9 + + # 拖动窗口相关变量 + self._drag_position = QPoint() + self._is_dragging = False + # 初始化UI (从Ui_install.py导入) self.ui = Ui_MainWindows() self.ui.setupUi(self) + # 设置圆角窗口 + self.setRoundedCorners() + # 初始化配置 self.config = load_config() @@ -57,6 +79,12 @@ class MainWindow(QMainWindow): self.debug_manager = DebugManager(self) self.download_manager = DownloadManager(self) + # 设置关闭按钮事件连接 + if hasattr(self.ui, 'close_btn'): + self.ui.close_btn.clicked.connect(self.close) + + if hasattr(self.ui, 'minimize_btn'): + self.ui.minimize_btn.clicked.connect(self.showMinimized) # 检查管理员权限和进程 self.admin_privileges.request_admin_privileges() @@ -78,9 +106,13 @@ class MainWindow(QMainWindow): sys.exit(1) # 连接信号 - 绑定到新按钮 - self.ui.start_install_btn.clicked.connect(self.download_manager.file_dialog) + self.ui.start_install_btn.clicked.connect(self.handle_install_button_click) self.ui.exit_btn.clicked.connect(self.shutdown_app) + # 初始化按钮状态标记 + self.install_button_enabled = False + self.last_error_message = "" + # 根据初始配置决定是否开启Debug模式 if hasattr(self.ui_manager, 'debug_action') and self.ui_manager.debug_action: if self.ui_manager.debug_action.isChecked(): @@ -92,6 +124,94 @@ class MainWindow(QMainWindow): # 窗口显示后延迟100ms启动动画 QTimer.singleShot(100, self.start_animations) + def setRoundedCorners(self): + """设置窗口圆角""" + # 实现圆角窗口 + path = QPainterPath() + path.addRoundedRect(self.rect(), 20, 20) + mask = QRegion(path.toFillPolygon().toPolygon()) + self.setMask(mask) + + # 更新resize事件时更新圆角 + self.updateRoundedCorners = True + + # 添加鼠标事件处理,实现窗口拖动 + def mousePressEvent(self, event): + if event.button() == Qt.MouseButton.LeftButton: + # 只有当鼠标在标题栏区域时才可以拖动 + if hasattr(self.ui, 'title_bar') and self.ui.title_bar.geometry().contains(event.position().toPoint()): + self._is_dragging = True + self._drag_position = event.globalPosition().toPoint() - self.frameGeometry().topLeft() + event.accept() + + def mouseMoveEvent(self, event): + if event.buttons() & Qt.MouseButton.LeftButton and self._is_dragging: + self.move(event.globalPosition().toPoint() - self._drag_position) + event.accept() + + def mouseReleaseEvent(self, event): + if event.button() == Qt.MouseButton.LeftButton: + self._is_dragging = False + event.accept() + + def resizeEvent(self, event): + """当窗口大小改变时更新圆角和维持纵横比""" + # 计算基于当前宽度的合适高度,以维持16:9比例 + new_width = event.size().width() + new_height = int(new_width / self.aspect_ratio) + + if new_height != event.size().height(): + # 阻止变形,保持比例 + self.resize(new_width, new_height) + + # 更新主容器大小 + if hasattr(self.ui, 'main_container'): + self.ui.main_container.setGeometry(0, 0, new_width, new_height) + + # 更新内容容器大小 + if hasattr(self.ui, 'content_container'): + self.ui.content_container.setGeometry(0, 0, new_width, new_height) + + # 更新标题栏宽度 + if hasattr(self.ui, 'title_bar'): + self.ui.title_bar.setGeometry(0, 0, new_width, 30) + + # 更新内容区域大小 + if hasattr(self.ui, 'inner_content'): + self.ui.inner_content.setGeometry(0, 55, new_width, new_height - 55) + + # 更新背景图大小 + if hasattr(self.ui, 'Mainbg'): + self.ui.Mainbg.setGeometry(0, 0, new_width, new_height - 55) + + if hasattr(self.ui, 'loadbg'): + self.ui.loadbg.setGeometry(0, 0, new_width, new_height - 55) + + # 调整按钮位置 - 固定在右侧 + right_margin = 20 # 减小右边距,使按钮更靠右 + if hasattr(self.ui, 'button_container'): + btn_width = 211 # 扩大后的容器宽度 + btn_height = 111 # 扩大后的容器高度 + x_pos = new_width - btn_width - right_margin + y_pos = int((new_height - 55) * 0.42) - 10 # 调整Y位置以适应扩大的容器 + self.ui.button_container.setGeometry(x_pos, y_pos, btn_width, btn_height) + + if hasattr(self.ui, 'exit_container'): + btn_width = 211 # 扩大后的容器宽度 + btn_height = 111 # 扩大后的容器高度 + x_pos = new_width - btn_width - right_margin + y_pos = int((new_height - 55) * 0.62) - 10 # 调整Y位置以适应扩大的容器 + self.ui.exit_container.setGeometry(x_pos, y_pos, btn_width, btn_height) + + # 更新圆角 + if hasattr(self, 'updateRoundedCorners') and self.updateRoundedCorners: + path = QPainterPath() + path.addRoundedRect(self.rect(), 20, 20) + mask = QRegion(path.toFillPolygon().toPolygon()) + self.setMask(mask) + + super().resizeEvent(event) + def start_animations(self): """开始启动动画""" # 不再禁用退出按钮的交互性,只通过样式表控制外观 @@ -100,7 +220,7 @@ class MainWindow(QMainWindow): # 按钮容器初始是隐藏的,无需在这里禁用 # 但确保开始安装按钮仍然处于禁用状态 - self.ui.start_install_btn.setEnabled(False) + self.set_start_button_enabled(False) self.animator.animation_finished.connect(self.on_animations_finished) self.animator.start_animations() @@ -112,9 +232,26 @@ class MainWindow(QMainWindow): # 只有在配置有效时才启用开始安装按钮 if self.config_valid: - self.ui.start_install_btn.setEnabled(True) + self.set_start_button_enabled(True) else: - self.ui.start_install_btn.setEnabled(False) + self.set_start_button_enabled(False) + + def set_start_button_enabled(self, enabled): + """设置开始安装按钮的启用状态和视觉效果 + + Args: + enabled: 是否启用按钮 + """ + self.ui.start_install_btn.setEnabled(True) # 始终启用按钮,以便捕获点击事件 + + # 根据状态修改文本内容,但不再修改颜色样式 + if enabled: + self.ui.start_install_text.setText("开始安装") + else: + self.ui.start_install_text.setText("!无法安装!") + + # 记录当前按钮状态,用于点击事件处理 + self.install_button_enabled = enabled def fetch_cloud_config(self): """获取云端配置""" @@ -134,6 +271,8 @@ class MainWindow(QMainWindow): if error_message: # 标记配置无效 self.config_valid = False + # 记录错误信息,用于按钮点击时显示 + self.last_error_message = error_message if error_message == "update_required": msg_box = msgbox_frame( @@ -175,18 +314,20 @@ class MainWindow(QMainWindow): ) msg_box.exec() # 在无法连接到云端时禁用开始安装按钮 - self.ui.start_install_btn.setEnabled(False) + self.set_start_button_enabled(False) else: self.cloud_config = data # 标记配置有效 self.config_valid = True + # 清除错误信息 + self.last_error_message = "" debug_mode = self.ui_manager.debug_action.isChecked() if self.ui_manager.debug_action else False if debug_mode: print("--- Cloud config fetched successfully ---") print(json.dumps(data, indent=2)) # 确保按钮在成功获取配置时启用 - self.ui.start_install_btn.setEnabled(True) + self.set_start_button_enabled(True) def toggle_debug_mode(self, checked): """切换调试模式 @@ -290,7 +431,7 @@ class MainWindow(QMainWindow): # 重新启用退出按钮和开始安装按钮 self.ui.exit_btn.setEnabled(True) - self.ui.start_install_btn.setEnabled(True) + self.set_start_button_enabled(True) # 添加短暂延迟确保UI更新 QTimer.singleShot(100, self.show_result) @@ -424,4 +565,29 @@ class MainWindow(QMainWindow): else: sys.exit(0) + def handle_install_button_click(self): + """处理安装按钮点击事件 + 根据按钮当前状态决定是显示错误还是执行安装 + """ + if not self.install_button_enabled: + # 按钮处于"无法安装"状态,显示上次错误消息 + if self.last_error_message == "update_required": + msg_box = msgbox_frame( + f"更新提示 - {APP_NAME}", + "\n当前版本过低,请及时更新。\n", + QMessageBox.StandardButton.Ok, + ) + msg_box.exec() + else: + # 默认显示网络错误 + msg_box = msgbox_frame( + f"错误 - {APP_NAME}", + "\n访问云端配置失败,请检查网络状况或稍后再试。\n", + QMessageBox.StandardButton.Ok, + ) + msg_box.exec() + else: + # 按钮处于"开始安装"状态,正常执行安装流程 + self.download_manager.file_dialog() + \ No newline at end of file diff --git a/source/ui/Ui_install.py b/source/ui/Ui_install.py index d73a3fa..20b70f5 100644 --- a/source/ui/Ui_install.py +++ b/source/ui/Ui_install.py @@ -8,9 +8,9 @@ from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient, QCursor, QFont, QFontDatabase, QGradient, QIcon, QImage, QKeySequence, QLinearGradient, QPainter, QPalette, QPixmap, QRadialGradient, - QTransform) + QTransform, QPainterPath, QRegion) from PySide6.QtWidgets import (QApplication, QLabel, QMainWindow, QMenu, - QMenuBar, QPushButton, QSizePolicy, QWidget) + QMenuBar, QPushButton, QSizePolicy, QWidget, QHBoxLayout) import os def load_base64_image(base64_str): @@ -28,13 +28,15 @@ class Ui_MainWindows(object): if not MainWindows.objectName(): MainWindows.setObjectName(u"MainWindows") MainWindows.setEnabled(True) - MainWindows.resize(1024, 576) - MainWindows.setMinimumSize(QSize(1024, 576)) - MainWindows.setMaximumSize(QSize(1024, 576)) + # 调整窗口默认大小为1280x720以匹配背景图片 + MainWindows.resize(1280, 720) + # 移除最大和最小尺寸限制,允许自由缩放 + # MainWindows.setMinimumSize(QSize(1024, 576)) + # MainWindows.setMaximumSize(QSize(1024, 576)) MainWindows.setMouseTracking(False) MainWindows.setTabletTracking(False) MainWindows.setAcceptDrops(True) - MainWindows.setAutoFillBackground(True) + MainWindows.setAutoFillBackground(False) MainWindows.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) MainWindows.setAnimated(True) MainWindows.setDocumentMode(False) @@ -48,41 +50,274 @@ class Ui_MainWindows(object): self.centralwidget = QWidget(MainWindows) self.centralwidget.setObjectName(u"centralwidget") - self.centralwidget.setAutoFillBackground(True) - self.loadbg = QLabel(self.centralwidget) + self.centralwidget.setAutoFillBackground(False) # 修改为False以支持透明背景 + self.centralwidget.setStyleSheet(""" + QWidget#centralwidget { + background-color: transparent; + } + """) + + # 圆角背景容器 + self.main_container = QWidget(self.centralwidget) + self.main_container.setObjectName(u"main_container") + self.main_container.setGeometry(QRect(0, 0, 1280, 720)) + self.main_container.setStyleSheet(""" + QWidget#main_container { + background-color: #C5DDFC; + border-radius: 20px; + border: 1px solid #A4C2F4; + } + """) + + # 内容容器 - 用于限制内容在圆角范围内 + self.content_container = QWidget(self.main_container) + self.content_container.setObjectName(u"content_container") + self.content_container.setGeometry(QRect(0, 0, 1280, 720)) + self.content_container.setStyleSheet(""" + QWidget#content_container { + background-color: transparent; + border-radius: 20px; + } + """) + + # 添加圆角裁剪,确保内容在圆角范围内 + rect = QRect(0, 0, 1280, 720) + path = QPainterPath() + path.addRoundedRect(rect, 20, 20) + region = QRegion(path.toFillPolygon().toPolygon()) + 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.setObjectName(u"title_bar") + self.title_bar.setGeometry(QRect(0, 0, 1280, 30)) + self.title_bar.setStyleSheet(""" + QWidget#title_bar { + background-color: #A4C2F4; + border-top-left-radius: 20px; + border-top-right-radius: 20px; + border-bottom: 1px solid #8AB4F8; + } + """) + + # 标题栏布局 + self.title_layout = QHBoxLayout(self.title_bar) + self.title_layout.setSpacing(10) + self.title_layout.setContentsMargins(10, 0, 10, 0) + + # 添加最小化和关闭按钮到标题栏 + self.minimize_btn = QPushButton(self.title_bar) + self.minimize_btn.setObjectName(u"minimize_btn") + self.minimize_btn.setMinimumSize(QSize(24, 24)) + self.minimize_btn.setMaximumSize(QSize(24, 24)) + self.minimize_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) + self.minimize_btn.setStyleSheet(""" + QPushButton { + background-color: #FFC107; + border-radius: 12px; + border: none; + } + QPushButton:hover { + background-color: #FFD54F; + } + QPushButton:pressed { + background-color: #FFA000; + } + """) + self.minimize_btn.setText("—") + self.minimize_btn.setFont(QFont(font_family, 10)) + + self.close_btn = QPushButton(self.title_bar) + self.close_btn.setObjectName(u"close_btn") + self.close_btn.setMinimumSize(QSize(24, 24)) + self.close_btn.setMaximumSize(QSize(24, 24)) + self.close_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) + self.close_btn.setStyleSheet(""" + QPushButton { + background-color: #F44336; + border-radius: 12px; + border: none; + color: white; + font-weight: bold; + } + QPushButton:hover { + background-color: #EF5350; + } + QPushButton:pressed { + background-color: #D32F2F; + } + """) + self.close_btn.setText("×") + self.close_btn.setFont(QFont(font_family, 14)) + + # 标题文本 + self.title_label = QLabel(self.title_bar) + self.title_label.setObjectName(u"title_label") + self.title_label.setText("FraiseMoe Addons Manager") + title_font = QFont(font_family, 12) + title_font.setBold(True) + self.title_label.setFont(title_font) + self.title_label.setStyleSheet("color: #333333; padding-left: 10px;") + self.title_label.setAlignment(Qt.AlignmentFlag.AlignCenter) + + # 添加按钮到标题栏布局 + self.title_layout.addWidget(self.title_label) + self.title_layout.addStretch(1) + self.title_layout.addWidget(self.minimize_btn) + self.title_layout.addSpacing(5) + self.title_layout.addWidget(self.close_btn) + + # 菜单区域 + self.menu_area = QWidget(self.content_container) + self.menu_area.setObjectName(u"menu_area") + self.menu_area.setGeometry(QRect(0, 30, 1024, 25)) + self.menu_area.setStyleSheet(""" + QWidget#menu_area { + background-color: #D4E4FC; + border-bottom: 1px solid #A4C2F4; + } + """) + + # 创建菜单栏在菜单区域中 + self.menubar = QMenuBar(self.menu_area) + self.menubar.setObjectName(u"menubar") + self.menubar.setGeometry(QRect(10, 2, 200, 20)) + self.menubar.setStyleSheet(""" + QMenuBar { + background-color: transparent; + color: #333333; + font-weight: bold; + spacing: 5px; + } + QMenuBar::item { + background-color: transparent; + padding: 1px 8px; + border-radius: 4px; + } + QMenuBar::item:selected { + background-color: rgba(0, 0, 0, 0.1); + } + 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; + } + QMenu::item:selected { + background-color: rgba(0, 0, 0, 0.1); + } + """) + + # 内容子容器 + self.inner_content = QWidget(self.content_container) + self.inner_content.setObjectName(u"inner_content") + # 确保宽度足够大,保证右侧元素完全显示 + self.inner_content.setGeometry(QRect(0, 55, 1280, 665)) + self.inner_content.setStyleSheet(""" + QWidget#inner_content { + background-color: transparent; + border-bottom-left-radius: 20px; + border-bottom-right-radius: 20px; + } + """) + + # 添加底部圆角裁剪 + inner_rect = QRect(0, 0, 1280, 665) + inner_path = QPainterPath() + inner_path.addRoundedRect(inner_rect, 20, 20) + inner_region = QRegion(inner_path.toFillPolygon().toPolygon()) + 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保持不变 + self.loadbg = QLabel(self.inner_content) self.loadbg.setObjectName(u"loadbg") - self.loadbg.setGeometry(QRect(0, 0, 1031, 561)) + self.loadbg.setGeometry(QRect(0, 0, 1280, 665)) # 调整尺寸 self.loadbg.setPixmap(load_base64_image(img_data["loadbg"])) self.loadbg.setScaledContents(True) - self.vol1bg = QLabel(self.centralwidget) + + self.vol1bg = QLabel(self.inner_content) self.vol1bg.setObjectName(u"vol1bg") - self.vol1bg.setGeometry(QRect(0, 120, 93, 64)) + self.vol1bg.setGeometry(QRect(0, 150, 93, 64)) self.vol1bg.setPixmap(load_base64_image(img_data["vol1"])) self.vol1bg.setScaledContents(True) - self.vol2bg = QLabel(self.centralwidget) + + self.vol2bg = QLabel(self.inner_content) self.vol2bg.setObjectName(u"vol2bg") - self.vol2bg.setGeometry(QRect(0, 180, 93, 64)) + self.vol2bg.setGeometry(QRect(0, 210, 93, 64)) self.vol2bg.setPixmap(load_base64_image(img_data["vol2"])) self.vol2bg.setScaledContents(True) - self.vol3bg = QLabel(self.centralwidget) + + self.vol3bg = QLabel(self.inner_content) self.vol3bg.setObjectName(u"vol3bg") - self.vol3bg.setGeometry(QRect(0, 240, 93, 64)) + self.vol3bg.setGeometry(QRect(0, 270, 93, 64)) self.vol3bg.setPixmap(load_base64_image(img_data["vol3"])) self.vol3bg.setScaledContents(True) - self.vol4bg = QLabel(self.centralwidget) + + self.vol4bg = QLabel(self.inner_content) self.vol4bg.setObjectName(u"vol4bg") - self.vol4bg.setGeometry(QRect(0, 300, 93, 64)) + self.vol4bg.setGeometry(QRect(0, 330, 93, 64)) self.vol4bg.setPixmap(load_base64_image(img_data["vol4"])) self.vol4bg.setScaledContents(True) - self.afterbg = QLabel(self.centralwidget) + + self.afterbg = QLabel(self.inner_content) self.afterbg.setObjectName(u"afterbg") - self.afterbg.setGeometry(QRect(0, 360, 93, 64)) + self.afterbg.setGeometry(QRect(0, 390, 93, 64)) self.afterbg.setPixmap(load_base64_image(img_data["after"])) self.afterbg.setScaledContents(True) - self.Mainbg = QLabel(self.centralwidget) + + # 修复Mainbg位置并使用title_bg1.png作为背景图片 + self.Mainbg = QLabel(self.inner_content) self.Mainbg.setObjectName(u"Mainbg") - self.Mainbg.setGeometry(QRect(0, 0, 1031, 561)) - self.Mainbg.setPixmap(load_base64_image(img_data["Mainbg"])) + self.Mainbg.setGeometry(QRect(0, 0, 1280, 665)) # 调整尺寸 + 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) # 使用新的按钮图片 @@ -90,29 +325,30 @@ class Ui_MainWindows(object): # 创建文本标签布局的按钮 # 开始安装按钮 - 基于背景图片和标签组合 - self.button_container = QWidget(self.centralwidget) + self.button_container = QWidget(self.inner_content) self.button_container.setObjectName(u"start_install_container") - self.button_container.setGeometry(QRect(780, 250, 191, 91)) + self.button_container.setGeometry(QRect(1050, 285, 211, 111)) # 扩大容器尺寸,预留动画空间 # 不要隐藏容器,让动画系统来控制它的可见性和位置 - + + # 使用原来的按钮背景图片 self.start_install_bg = QLabel(self.button_container) self.start_install_bg.setObjectName(u"start_install_bg") - self.start_install_bg.setGeometry(QRect(0, 0, 191, 91)) + self.start_install_bg.setGeometry(QRect(10, 10, 191, 91)) # 居中放置在扩大的容器中 self.start_install_bg.setPixmap(button_pixmap) self.start_install_bg.setScaledContents(True) - + self.start_install_text = QLabel(self.button_container) self.start_install_text.setObjectName(u"start_install_text") - self.start_install_text.setGeometry(QRect(0, -3, 191, 91)) + self.start_install_text.setGeometry(QRect(10, 7, 191, 91)) # 居中放置在扩大的容器中 self.start_install_text.setText("开始安装") self.start_install_text.setFont(self.custom_font) self.start_install_text.setAlignment(Qt.AlignmentFlag.AlignCenter) - self.start_install_text.setStyleSheet("color: black; letter-spacing: 1px;") - + self.start_install_text.setStyleSheet("letter-spacing: 1px;") + # 点击区域透明按钮 self.start_install_btn = QPushButton(self.button_container) self.start_install_btn.setObjectName(u"start_install_btn") - self.start_install_btn.setGeometry(QRect(0, 0, 191, 91)) + self.start_install_btn.setGeometry(QRect(10, 10, 191, 91)) # 居中放置在扩大的容器中 self.start_install_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) # 设置鼠标悬停时为手形光标 self.start_install_btn.setFlat(True) self.start_install_btn.raise_() # 确保按钮在最上层 @@ -124,29 +360,30 @@ class Ui_MainWindows(object): """) # 退出按钮 - 基于背景图片和标签组合 - self.exit_container = QWidget(self.centralwidget) + self.exit_container = QWidget(self.inner_content) self.exit_container.setObjectName(u"exit_container") - self.exit_container.setGeometry(QRect(780, 340, 191, 91)) + self.exit_container.setGeometry(QRect(1050, 415, 211, 111)) # 扩大容器尺寸,预留动画空间 # 不要隐藏容器,让动画系统来控制它的可见性和位置 - + + # 使用原来的按钮背景图片 self.exit_bg = QLabel(self.exit_container) self.exit_bg.setObjectName(u"exit_bg") - self.exit_bg.setGeometry(QRect(0, 0, 191, 91)) + self.exit_bg.setGeometry(QRect(10, 10, 191, 91)) # 居中放置在扩大的容器中 self.exit_bg.setPixmap(button_pixmap) self.exit_bg.setScaledContents(True) - + self.exit_text = QLabel(self.exit_container) self.exit_text.setObjectName(u"exit_text") - self.exit_text.setGeometry(QRect(0, -3, 191, 91)) - self.exit_text.setText("退出") + self.exit_text.setGeometry(QRect(10, 7, 191, 91)) # 居中放置在扩大的容器中 + self.exit_text.setText("退出程序") self.exit_text.setFont(self.custom_font) self.exit_text.setAlignment(Qt.AlignmentFlag.AlignCenter) - self.exit_text.setStyleSheet("color: black; letter-spacing: 1px;") + self.exit_text.setStyleSheet("letter-spacing: 1px;") # 点击区域透明按钮 self.exit_btn = QPushButton(self.exit_container) self.exit_btn.setObjectName(u"exit_btn") - self.exit_btn.setGeometry(QRect(0, 0, 191, 91)) + self.exit_btn.setGeometry(QRect(10, 10, 191, 91)) # 居中放置在扩大的容器中 self.exit_btn.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) # 设置鼠标悬停时为手形光标 self.exit_btn.setFlat(True) self.exit_btn.raise_() # 确保按钮在最上层 @@ -157,12 +394,22 @@ class Ui_MainWindows(object): } """) - self.menubg = QLabel(self.centralwidget) - self.menubg.setObjectName(u"menubg") - self.menubg.setGeometry(QRect(710, 0, 321, 561)) - self.menubg.setPixmap(load_base64_image(img_data["menubg"])) - self.menubg.setScaledContents(True) + # 注释掉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) + + # 调整层级顺序 self.loadbg.raise_() self.vol1bg.raise_() self.vol2bg.raise_() @@ -170,21 +417,29 @@ class Ui_MainWindows(object): self.vol4bg.raise_() self.afterbg.raise_() self.Mainbg.raise_() - self.menubg.raise_() + # self.menubg.raise_() # 注释掉menubg + # 不再需要底部圆角装饰器 + # self.bottom_corner_left.raise_() + # self.bottom_corner_right.raise_() self.button_container.raise_() self.exit_container.raise_() - self.menubar = QMenuBar(MainWindows) - 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(self.menubar) + self.menu_area.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.menubar.addAction(self.menu.menuAction()) + # self.menubar.addAction(self.menu_2.menuAction()) + # self.menu.addSeparator() self.retranslateUi(MainWindows) QMetaObject.connectSlotsByName(MainWindows) @@ -202,10 +457,7 @@ class Ui_MainWindows(object): #if QT_CONFIG(accessibility) self.start_install_btn.setAccessibleDescription("") #endif // QT_CONFIG(accessibility) - # 不再在这里设置文本,因为我们已经在setupUi中设置了 - # self.start_install_btn.setText("") - # self.exit_btn.setText("") - self.menubg.setText("") + # self.menubg.setText("") # 注释掉menubg self.menu.setTitle(QCoreApplication.translate("MainWindows", u"\u8bbe\u7f6e", None)) self.menu_2.setTitle(QCoreApplication.translate("MainWindows", u"\u5e2e\u52a9", None)) # retranslateUi