Files
shuidrop_gui/custom_update_dialog.py

345 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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)