[patch] 优化更新提示逻辑 与 样式细节

This commit is contained in:
2025-10-30 16:54:24 +08:00
parent 5440aa7d6d
commit 8575de6ea5
2 changed files with 459 additions and 34 deletions

344
custom_update_dialog.py Normal file
View File

@@ -0,0 +1,344 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
自定义版本更新对话框
美观的布局和用户体验
"""
from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel,
QPushButton, QTextEdit, QFrame)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QCursor
class UpdateNotificationDialog(QDialog):
"""
版本更新提示对话框
布局:
- 标题区
- 更新内容区
- 下载地址区(可复制)
- 按钮区(两行,美观布局)
"""
# 用户选择(返回值)
CHOICE_UPDATE_NOW = 1 # 立即更新
CHOICE_UPDATE_LATER = 2 # 稍后更新
CHOICE_IGNORE = 3 # 忽略此版本
def __init__(self, version, download_url, update_content="", parent=None):
super().__init__(parent)
self.version = version
self.download_url = download_url
self.update_content = update_content
self.user_choice = None
self.init_ui()
def init_ui(self):
"""初始化UI"""
self.setWindowTitle("版本更新")
self.setFixedWidth(550)
self.setMinimumHeight(400)
# 禁用关闭按钮(只能通过按钮关闭)
self.setWindowFlags(Qt.Dialog | Qt.WindowTitleHint | Qt.CustomizeWindowHint)
# 主布局
layout = QVBoxLayout()
layout.setSpacing(15)
layout.setContentsMargins(25, 20, 25, 20)
# ============ 标题区 ============
title_label = QLabel(f"🔔 发现新版本 v{self.version}")
title_label.setFont(QFont('Microsoft YaHei', 14, QFont.Bold))
title_label.setAlignment(Qt.AlignCenter)
title_label.setStyleSheet("color: #2c3e50; margin-bottom: 5px;")
layout.addWidget(title_label)
# 分隔线
line1 = QFrame()
line1.setFrameShape(QFrame.HLine)
line1.setStyleSheet("background: #ddd; max-height: 1px;")
layout.addWidget(line1)
# ============ 更新内容区(可选)============
# 🔥 只有在有更新内容时才显示
if self.update_content and self.update_content.strip():
content_label = QLabel("📝 更新内容:")
content_label.setFont(QFont('Microsoft YaHei', 10, QFont.Bold))
content_label.setStyleSheet("color: #34495e;")
layout.addWidget(content_label)
# 更新内容文本
content_text = QTextEdit()
content_text.setReadOnly(True)
content_text.setMaximumHeight(100)
content_text.setStyleSheet("""
QTextEdit {
border: 1px solid #ddd;
border-radius: 6px;
padding: 8px;
background: #f8f9fa;
font-size: 11px;
color: #555;
}
""")
content_text.setText(self.update_content)
layout.addWidget(content_text)
# ============ 下载地址区 ============
url_label = QLabel("📥 下载地址:")
url_label.setFont(QFont('Microsoft YaHei', 10, QFont.Bold))
url_label.setStyleSheet("color: #34495e; margin-top: 5px;")
layout.addWidget(url_label)
# 下载地址文本框(可选择复制)
self.url_text = QTextEdit()
self.url_text.setReadOnly(True)
self.url_text.setMaximumHeight(60)
self.url_text.setText(self.download_url)
self.url_text.setStyleSheet("""
QTextEdit {
border: 2px solid #4285f4;
border-radius: 6px;
padding: 8px;
background: #e3f2fd;
font-size: 10px;
color: #1565c0;
font-family: 'Consolas', 'Courier New', monospace;
}
""")
# 全选文本,方便复制
self.url_text.selectAll()
layout.addWidget(self.url_text)
# 复制提示
copy_hint = QLabel("💡 提示:上方地址已自动选中,按 Ctrl+C 即可复制")
copy_hint.setFont(QFont('Microsoft YaHei', 8))
copy_hint.setStyleSheet("color: #7f8c8d;")
layout.addWidget(copy_hint)
# 分隔线
line2 = QFrame()
line2.setFrameShape(QFrame.HLine)
line2.setStyleSheet("background: #ddd; max-height: 1px; margin-top: 10px;")
layout.addWidget(line2)
# ============ 操作说明区 ============
hint_label = QLabel(
"• 在线自动更新:自动下载并安装新版本\n"
"• 稍后更新:保留提示在状态栏,可随时点击更新\n"
"• 忽略此版本:本次运行不再提示此版本"
)
hint_label.setFont(QFont('Microsoft YaHei', 9))
hint_label.setStyleSheet("color: #666; margin: 5px 0;")
layout.addWidget(hint_label)
# ============ 按钮区(两行布局)============
# 第一行:主要操作
button_row1 = QHBoxLayout()
button_row1.setSpacing(10)
self.update_now_btn = QPushButton("🚀 在线自动更新")
self.update_now_btn.setFont(QFont('Microsoft YaHei', 11, QFont.Bold))
self.update_now_btn.setMinimumHeight(42)
self.update_now_btn.setCursor(QCursor(Qt.PointingHandCursor))
self.update_now_btn.clicked.connect(self.on_update_now)
self.update_later_btn = QPushButton("⏰ 稍后更新")
self.update_later_btn.setFont(QFont('Microsoft YaHei', 11))
self.update_later_btn.setMinimumHeight(42)
self.update_later_btn.setCursor(QCursor(Qt.PointingHandCursor))
self.update_later_btn.clicked.connect(self.on_update_later)
button_row1.addWidget(self.update_now_btn)
button_row1.addWidget(self.update_later_btn)
layout.addLayout(button_row1)
# 第二行:次要操作
button_row2 = QHBoxLayout()
button_row2.setSpacing(10)
self.ignore_btn = QPushButton("🚫 忽略此版本")
self.ignore_btn.setFont(QFont('Microsoft YaHei', 10))
self.ignore_btn.setMinimumHeight(38)
self.ignore_btn.setCursor(QCursor(Qt.PointingHandCursor))
self.ignore_btn.clicked.connect(self.on_ignore)
self.copy_btn = QPushButton("📋 复制下载地址")
self.copy_btn.setFont(QFont('Microsoft YaHei', 10))
self.copy_btn.setMinimumHeight(38)
self.copy_btn.setCursor(QCursor(Qt.PointingHandCursor))
self.copy_btn.clicked.connect(self.on_copy_url)
button_row2.addWidget(self.ignore_btn)
button_row2.addWidget(self.copy_btn)
layout.addLayout(button_row2)
self.setLayout(layout)
# 应用样式
self.apply_styles()
def apply_styles(self):
"""应用现代化样式"""
self.setStyleSheet("""
QDialog {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #f8fafb,
stop:1 #e8ecef
);
}
/* 主要操作按钮(立即更新、稍后更新)*/
QPushButton#updateNowBtn {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #4285f4,
stop:1 #1565c0
);
border: none;
color: white;
border-radius: 8px;
font-weight: bold;
}
QPushButton#updateNowBtn:hover {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #5294f5,
stop:1 #1e74c1
);
}
QPushButton#updateLaterBtn {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #ff9800,
stop:1 #f57c00
);
border: none;
color: white;
border-radius: 8px;
}
QPushButton#updateLaterBtn:hover {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #ffa726,
stop:1 #fb8c00
);
}
/* 次要操作按钮(忽略、复制)*/
QPushButton {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #f5f5f5,
stop:1 #e0e0e0
);
border: 2px solid #ccc;
border-radius: 8px;
color: #555;
}
QPushButton:hover {
background: qlineargradient(
x1:0, y1:0, x2:0, y2:1,
stop:0 #e8e8e8,
stop:1 #d0d0d0
);
border: 2px solid #999;
}
""")
# 设置按钮对象名以应用特定样式
self.update_now_btn.setObjectName("updateNowBtn")
self.update_later_btn.setObjectName("updateLaterBtn")
def on_update_now(self):
"""立即更新"""
self.user_choice = self.CHOICE_UPDATE_NOW
self.accept()
def on_update_later(self):
"""稍后更新"""
self.user_choice = self.CHOICE_UPDATE_LATER
self.accept()
def on_ignore(self):
"""忽略此版本"""
self.user_choice = self.CHOICE_IGNORE
self.accept()
def on_copy_url(self):
"""复制下载地址"""
from PyQt5.QtWidgets import QApplication, QMessageBox
clipboard = QApplication.clipboard()
clipboard.setText(self.download_url)
# 显示复制成功提示(不关闭主对话框)
QMessageBox.information(
self,
"复制成功",
f"✅ 下载地址已复制到剪贴板!\n\n"
f"您可以直接粘贴(Ctrl+V)到浏览器下载。",
QMessageBox.Ok
)
def get_user_choice(self):
"""获取用户选择"""
return self.user_choice
if __name__ == "__main__":
# 测试对话框
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
print("=" * 60)
print("测试更新对话框")
print("=" * 60)
print("\n场景1有更新内容")
dialog = UpdateNotificationDialog(
version="1.5.64",
download_url="https://shuidrop-chat-server.ks3-cn-guangzhou.ksyuncs.com/installers/ShuiDi_AI_Assistant_Setup_v1.5.64.exe",
update_content="• 修复了DY图片/视频上传问题\n• 优化了自动更新流程\n• 添加了圆形进度条"
)
dialog.exec_()
choice = dialog.get_user_choice()
if choice == UpdateNotificationDialog.CHOICE_UPDATE_NOW:
print("\n用户选择:在线自动更新")
elif choice == UpdateNotificationDialog.CHOICE_UPDATE_LATER:
print("\n用户选择:稍后更新")
elif choice == UpdateNotificationDialog.CHOICE_IGNORE:
print("\n用户选择:忽略此版本")
else:
print("\n用户关闭了对话框")
# 测试场景2无更新内容
print("\n" + "=" * 60)
print("场景2无更新内容应该隐藏更新内容区域")
print("=" * 60)
dialog2 = UpdateNotificationDialog(
version="1.5.65",
download_url="https://shuidrop-chat-server.ks3-cn-guangzhou.ksyuncs.com/installers/ShuiDi_AI_Assistant_Setup_v1.5.65.exe",
update_content="" # 空内容
)
dialog2.exec_()
print("\n测试完成!")
sys.exit(0)