345 lines
12 KiB
Python
345 lines
12 KiB
Python
#!/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)
|
||
|