Files
leonapp/pyqt5fluentdesign/app_detail_window.py

840 lines
33 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.

# 这破代码有人能修复吗
from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QPushButton, QFrame, QLabel, QGridLayout)
from PyQt5.QtCore import Qt, QSize, pyqtSignal, QThread
from PyQt5.QtGui import QPixmap, QFont
from qfluentwidgets import (InfoBar, InfoBarPosition, TitleLabel, SubtitleLabel,
PrimaryPushButton, PushButton, ScrollArea, CardWidget,
FluentIcon, SimpleCardWidget, BodyLabel)
import json
import os
import requests
import sys
import tempfile
import subprocess
import platform
class DownloadThread(QThread):
"""下载线程,用于在后台下载文件"""
progress = pyqtSignal(int)
finished = pyqtSignal(str)
error = pyqtSignal(str)
def __init__(self, download_url, save_path):
super().__init__()
self.download_url = download_url
self.save_path = save_path
def run(self):
"""线程运行函数"""
try:
# 发送请求
with requests.get(self.download_url, stream=True, timeout=30) as response:
response.raise_for_status()
# 获取文件大小
total_size = int(response.headers.get('content-length', 0))
downloaded_size = 0
# 创建保存目录
os.makedirs(os.path.dirname(self.save_path), exist_ok=True)
# 下载文件
with open(self.save_path, 'wb') as file:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
file.write(chunk)
downloaded_size += len(chunk)
# 计算进度
if total_size > 0:
progress = int(downloaded_size / total_size * 100)
self.progress.emit(progress)
# 下载完成
self.finished.emit(self.save_path)
except Exception as e:
self.error.emit(f"下载失败: {str(e)}")
class AppDetailWindow(QMainWindow):
def __init__(self, api_client, app_id, parent=None):
super().__init__(parent)
self.api_client = api_client
self.app_id = app_id
self.parent_window = parent
# 设置窗口属性
self.setWindowTitle("应用详情")
self.resize(850, 650)
self.setObjectName("AppDetailWindow")
# 添加全局样式 - 现代扁平化设计
self.setStyleSheet("""
#AppDetailWindow {
background-color: #F5F7FA;
}
QLabel {
color: #333333;
}
#AppTitle {
color: #1A1A1A;
font-weight: bold;
}
#StatusBadge {
border-radius: 12px;
padding: 2px 10px;
font-size: 12px;
}
#DeveloperLabel {
color: #666666;
font-size: 14px;
}
""")
# 创建中心部件
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
# 创建主布局
self.main_layout = QVBoxLayout(self.central_widget)
self.main_layout.setContentsMargins(0, 0, 0, 0)
self.main_layout.setSpacing(0)
# 创建自定义顶部区域(非传统顶栏)
self.create_custom_header()
# 添加分隔线
separator = QFrame()
separator.setFrameShape(QFrame.HLine)
separator.setFrameShadow(QFrame.Sunken)
separator.setStyleSheet("background-color: #E5E6EB;")
self.main_layout.addWidget(separator)
# 创建滚动区域 - 使用QFluentWidgets的ScrollArea
self.scroll_area = ScrollArea()
self.scroll_area.setWidgetResizable(True)
self.scroll_area.setFrameShape(0)
self.scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# 设置滚动区域样式
self.scroll_area.setStyleSheet("""
ScrollArea {
background-color: #F5F7FA;
border: none;
}
QScrollBar:vertical {
width: 10px;
background: transparent;
margin-right: 5px;
}
QScrollBar::handle:vertical {
background: rgba(142, 142, 147, 0.2);
border-radius: 5px;
min-height: 50px;
}
QScrollBar::handle:vertical:hover {
background: rgba(142, 142, 147, 0.4);
}
QScrollBar::add-line:vertical,
QScrollBar::sub-line:vertical {
height: 0px;
width: 0px;
}
""")
# 创建滚动内容部件
self.scroll_content = QWidget()
self.scroll_content.setObjectName("ScrollContent")
self.scroll_layout = QVBoxLayout(self.scroll_content)
self.scroll_layout.setContentsMargins(20, 20, 20, 30)
self.scroll_layout.setSpacing(20)
# 添加滚动区域到主布局
self.scroll_area.setWidget(self.scroll_content)
self.main_layout.addWidget(self.scroll_area)
# 加载应用详情
self.load_app_detail()
def create_custom_header(self):
"""创建自定义顶部区域"""
self.header_widget = QWidget()
self.header_widget.setObjectName("HeaderWidget")
self.header_widget.setStyleSheet("""
#HeaderWidget {
background-color: #FFFFFF;
padding: 15px 20px;
}
""")
self.header_layout = QHBoxLayout(self.header_widget)
self.header_layout.setContentsMargins(0, 0, 0, 0)
self.header_layout.setSpacing(15)
# 应用图标占位 - 使用QLabel替换Avatar
self.app_icon = QLabel()
self.app_icon.setFixedSize(60, 60)
self.app_icon.setStyleSheet("background-color: #4CAF50; border-radius: 12px;")
# 应用信息布局
self.app_info_layout = QVBoxLayout()
self.app_info_layout.setContentsMargins(0, 0, 0, 0)
self.app_info_layout.setSpacing(5)
# 标题和状态布局
self.title_status_layout = QHBoxLayout()
self.title_status_layout.setSpacing(10)
# 应用标题
self.app_title = TitleLabel("加载中...")
self.app_title.setObjectName("AppTitle")
self.title_status_layout.addWidget(self.app_title)
# 应用状态标签
self.status_badge = QLabel("- ")
self.status_badge.setObjectName("StatusBadge")
self.status_badge.setStyleSheet("background-color: #E5E6EB; color: #666666;")
self.status_badge.setAlignment(Qt.AlignCenter)
self.status_badge.setFixedHeight(24)
self.title_status_layout.addWidget(self.status_badge)
self.title_status_layout.addStretch()
# 开发者标签
self.developer_label = QLabel("开发者: 加载中...")
self.developer_label.setObjectName("DeveloperLabel")
# 添加到应用信息布局
self.app_info_layout.addLayout(self.title_status_layout)
self.app_info_layout.addWidget(self.developer_label)
# 右侧按钮布局
self.button_layout = QVBoxLayout()
self.button_layout.setContentsMargins(0, 0, 0, 0)
self.button_layout.setSpacing(8)
# 关闭按钮
self.close_button = PushButton("关闭")
self.close_button.clicked.connect(self.close)
self.close_button.setFixedSize(90, 32)
self.button_layout.addWidget(self.close_button)
self.button_layout.addStretch()
# 添加到主头部布局
self.header_layout.addWidget(self.app_icon)
self.header_layout.addLayout(self.app_info_layout, 1)
self.header_layout.addLayout(self.button_layout)
# 添加到主布局
self.main_layout.addWidget(self.header_widget)
def load_app_detail(self):
"""加载应用详情"""
try:
# 使用API客户端调用getappinfo端点获取应用详情
result = self.api_client.make_request('getappinfo', {'id': self.app_id})
# 检查API调用是否成功
if isinstance(result, dict) and 'success' in result and result['success']:
# 保存应用数据到实例属性
self.app_data = result['data']
# 为了保持向后兼容性,也保留局部变量
app_data = self.app_data
else:
# API调用失败显示错误信息
error_msg = result.get('error', '未知错误') if isinstance(result, dict) else 'API调用失败'
InfoBar.error(
title="错误",
content=f"加载应用详情失败: {error_msg}",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP,
parent=self
)
# 使用默认数据
self.app_data = {
"id": self.app_id,
"name": "未知应用",
"description": "无法加载应用详情",
"developer_id": "0",
"developer_name": "未知开发者",
"status": "unknown",
"version": "0.0.0",
"created_at": "-",
"downloads": "0",
"rating": "0.0",
"category": "未知"
}
app_data = self.app_data
# 更新窗口标题
self.setWindowTitle(f"应用详情 - {app_data.get('name', '未知应用')}")
# 更新头部信息
self.app_title.setText(app_data.get('name', '未知应用'))
# 通过开发者ID查询开发者名称
developer_id = app_data.get('developer_id', '')
result2 = self.api_client.make_request('getdeveloperinfo', {'id': developer_id})
developer_name = "未知开发者"
if developer_id and developer_id != "0":
# 尝试通过API获取开发者名称
try:
developer_info = self.api_client.make_request('getdeveloperinfo', {'id': developer_id})
if isinstance(developer_info, dict) and 'success' in developer_info and developer_info['success']:
developer_name = result2['data'].get('username')
else:
# 如果API调用失败尝试从本地数据获取
if 'developer_name' in app_data and app_data['developer_name']:
developer_name = app_data['developer_name']
elif 'developer' in app_data and app_data['developer']:
developer_name = app_data['developer']
elif 'developer_email' in app_data and app_data['developer_email']:
developer_name = app_data['developer_email']
except Exception as e:
# 异常处理,使用本地数据
if 'developer_name' in app_data and app_data['developer_name']:
developer_name = app_data['developer_name']
elif 'developer' in app_data and app_data['developer']:
developer_name = app_data['developer']
elif 'developer_email' in app_data and app_data['developer_email']:
developer_name = app_data['developer_email']
else:
# 如果没有有效的开发者ID尝试从本地数据获取
if 'developer_name' in app_data and app_data['developer_name']:
developer_name = app_data['developer_name']
elif 'developer' in app_data and app_data['developer']:
developer_name = app_data['developer']
elif 'developer_email' in app_data and app_data['developer_email']:
developer_name = app_data['developer_email']
self.developer_label.setText(f"开发者: {developer_name}")
# 根据应用状态设置状态标签样式
status = app_data.get('status', 'unknown')
status_text = {}
status_styles = {}
status_text['approved'] = '已通过'
status_text['pending'] = '审核中'
status_text['rejected'] = '已拒绝'
status_text['unknown'] = '未知状态'
status_styles['approved'] = 'background-color: #E8F5E9; color: #2E7D32;'
status_styles['pending'] = 'background-color: #FFF3E0; color: #E65100;'
status_styles['rejected'] = 'background-color: #FFEBEE; color: #C62828;'
status_styles['unknown'] = 'background-color: #E5E6EB; color: #666666;'
self.status_badge.setText(status_text.get(status, '未知状态'))
self.status_badge.setStyleSheet(status_styles.get(status, status_styles['unknown']))
# 清空滚动区域
for i in reversed(range(self.scroll_layout.count())):
widget = self.scroll_layout.itemAt(i).widget()
if widget is not None:
widget.setParent(None)
widget.deleteLater()
# 显示统计信息卡片
self.display_stats_card(app_data)
# 显示应用基本信息卡片
self.display_app_info_card(app_data)
# 显示应用描述卡片
self.display_description_card(app_data)
# 显示操作按钮区域
self.display_action_buttons()
except Exception as e:
InfoBar.error(
title="错误",
content=f"加载应用详情失败: {str(e)}",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP,
duration=3000,
parent=self
)
def display_stats_card(self, app_data):
"""显示应用统计信息卡片"""
stats_card = CardWidget()
stats_card.setObjectName("StatsCard")
stats_card.setStyleSheet("""
#StatsCard {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
/* color: white; */
border-radius: 12px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}
#StatsCard QLabel {
/* color: white; */
}
""")
card_layout = QHBoxLayout(stats_card)
card_layout.setContentsMargins(20, 20, 20, 20)
card_layout.setSpacing(25)
# 下载量统计项
downloads_item = QVBoxLayout()
downloads_label = BodyLabel("下载量")
downloads_label.setStyleSheet("font-size: 13px; opacity: 0.9;")
downloads_value = TitleLabel(app_data.get("downloads", "0"))
downloads_value.setStyleSheet("font-size: 24px; font-weight: bold;")
downloads_item.addWidget(downloads_label)
downloads_item.addWidget(downloads_value)
downloads_item.setAlignment(Qt.AlignCenter)
# 评分统计项
rating_item = QVBoxLayout()
rating_label = BodyLabel("评分")
rating_label.setStyleSheet("font-size: 13px; opacity: 0.9;")
rating_value = TitleLabel(app_data.get("rating", "0.0"))
rating_value.setStyleSheet("font-size: 24px; font-weight: bold;")
rating_item.addWidget(rating_label)
rating_item.addWidget(rating_value)
rating_item.setAlignment(Qt.AlignCenter)
# 分类统计项
category_item = QVBoxLayout()
category_label = BodyLabel("分类")
category_label.setStyleSheet("font-size: 13px; opacity: 0.9;")
category_value = TitleLabel(app_data.get("category", "未分类"))
category_value.setStyleSheet("font-size: 24px; font-weight: bold;")
category_item.addWidget(category_label)
category_item.addWidget(category_value)
category_item.setAlignment(Qt.AlignCenter)
# 添加到卡片布局
card_layout.addLayout(downloads_item)
card_layout.addLayout(rating_item)
card_layout.addLayout(category_item)
self.scroll_layout.addWidget(stats_card)
def display_app_info_card(self, app_data):
"""显示应用基本信息卡片"""
info_card = CardWidget()
info_card.setObjectName("InfoCard")
info_card.setStyleSheet("""
#InfoCard {
background-color: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
""")
card_layout = QVBoxLayout(info_card)
card_layout.setContentsMargins(20, 20, 20, 20)
card_layout.setSpacing(15)
# 卡片标题和图标
title_layout = QHBoxLayout()
title_icon = QLabel()
title_icon.setPixmap(FluentIcon.INFO.icon().pixmap(18, 18))
title_icon.setStyleSheet("color: #4CAF50;")
card_title = SubtitleLabel("基本信息")
card_title.setStyleSheet("font-size: 16px; font-weight: 600;")
title_layout.addWidget(title_icon)
title_layout.addWidget(card_title)
title_layout.addStretch()
card_layout.addLayout(title_layout)
# 信息网格布局 - 使用两列布局
info_grid_layout = QGridLayout()
info_grid_layout.setSpacing(12)
info_grid_layout.setColumnStretch(0, 1)
info_grid_layout.setColumnStretch(1, 1)
# 添加基本信息字段,对开发者信息进行特殊处理
print(app_data)
developer_id = app_data.get('developer_id')
print(developer_id)
result2 = self.api_client.make_request('getdeveloperinfo', {'id': developer_id})
result2 = result2["data"]
print(result2)
developer_name = result2.get("username")
print(developer_name)
if not developer_name:
developer_name = result2.get("username")
info_items = [
("应用ID", app_data.get("id", "--")),
("开发者", developer_name),
("当前版本", app_data.get("version", "--")),
("创建时间", app_data.get("created_at", "--"))
]
row = 0
for label_text, value_text in info_items:
# 创建标签和值
label = QLabel(f"{label_text}:")
label.setStyleSheet("color: #666666; font-size: 14px;")
# 确保value_text是字符串类型
value = QLabel(str(value_text))
value.setStyleSheet("color: #333333; font-size: 14px; font-weight: 500;")
value.setTextInteractionFlags(Qt.TextSelectableByMouse)
# 布局
item_layout = QVBoxLayout()
item_layout.addWidget(label)
item_layout.addWidget(value)
item_layout.setSpacing(4)
# 添加到网格
col = row % 2
actual_row = row // 2
info_grid_layout.addLayout(item_layout, actual_row, col)
row += 1
card_layout.addLayout(info_grid_layout)
self.scroll_layout.addWidget(info_card)
def display_description_card(self, app_data):
"""显示应用描述卡片"""
description_card = CardWidget()
description_card.setObjectName("DescriptionCard")
description_card.setStyleSheet("""
#DescriptionCard {
background-color: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
""")
card_layout = QVBoxLayout(description_card)
card_layout.setContentsMargins(20, 20, 20, 20)
card_layout.setSpacing(15)
# 卡片标题和图标
title_layout = QHBoxLayout()
title_icon = QLabel()
title_icon.setPixmap(FluentIcon.DOCUMENT.icon().pixmap(18, 18))
title_icon.setStyleSheet("color: #2196F3;")
card_title = SubtitleLabel("应用描述")
card_title.setStyleSheet("font-size: 16px; font-weight: 600;")
title_layout.addWidget(title_icon)
title_layout.addWidget(card_title)
title_layout.addStretch()
card_layout.addLayout(title_layout)
# 描述文本
from PyQt5.QtWidgets import QTextBrowser
description_text = QTextBrowser()
description_text.setReadOnly(True)
description_text.setWordWrapMode(3) # QTextOption.WrapAtWordBoundaryOrAnywhere
description_text.setMinimumHeight(200)
description_text.setOpenExternalLinks(False) # 禁用自动打开外部链接,由我们自己处理
description_text.setStyleSheet("""
QTextBrowser {
background-color: #FAFAFA;
border: 1px solid #E5E6EB;
border-radius: 8px;
padding: 12px;
font-family: 'Microsoft YaHei', 'SimHei';
font-size: 14px;
line-height: 1.6;
}
""")
# 设置描述内容 - 支持Markdown
description_text.setHtml(self.convert_markdown_to_html(app_data.get("description", "无描述信息")))
# 连接链接点击信号,处理外部链接打开
# QTextBrowser组件有anchorClicked信号可以连接到处理函数
description_text.anchorClicked.connect(self.handle_link_clicked)
card_layout.addWidget(description_text)
self.scroll_layout.addWidget(description_card)
def convert_markdown_to_html(self, markdown_text):
"""将Markdown文本转换为HTML"""
try:
import markdown
return markdown.markdown(markdown_text)
except Exception as e:
# 如果转换失败使用原始文本并进行HTML转义
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QTextDocument
# 创建QTextDocument进行HTML转义
doc = QTextDocument()
doc.setPlainText(markdown_text)
return doc.toHtml()
def handle_link_clicked(self, url):
"""处理链接点击事件,使用系统默认浏览器打开外部链接"""
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QDesktopServices
from qfluentwidgets import InfoBar
# 检查URL是否为http或https协议
if url.scheme() in ['http', 'https']:
# 使用系统默认浏览器打开链接
QDesktopServices.openUrl(url)
return
# 处理特殊的leonapp链接
elif url.toString().startswith('leonapp://'):
# 提取应用ID或其他参数
# 示例: leonapp://app/123
path = url.toString()[10:] # 移除 'leonapp://'
if path.startswith('app/'):
app_id = path[4:] # 提取应用ID
# 实现打开特定应用详情的逻辑
self.app_detail_window = AppDetailWindow(self.api_client, app_id, parent=self.parent())
self.app_detail_window.show()
return
# 显示不支持的链接类型提示
InfoBar.warning(
title="不支持的链接类型",
content=f"无法打开链接: {url.toString()}",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.BOTTOM_RIGHT,
duration=3000,
parent=self
)
def display_action_buttons(self):
"""显示操作按钮区域"""
button_card = CardWidget()
button_card.setObjectName("ButtonCard")
button_card.setStyleSheet("""
#ButtonCard {
background-color: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
""")
button_layout = QHBoxLayout(button_card)
button_layout.setContentsMargins(20, 20, 20, 20)
button_layout.setSpacing(12)
button_layout.addStretch()
# 刷新按钮
refresh_button = PushButton("刷新")
refresh_button.setIcon(FluentIcon.SYNC)
refresh_button.clicked.connect(self.load_app_detail)
refresh_button.setFixedSize(100, 36)
# 安装按钮
install_button = PrimaryPushButton("安装")
install_button.setIcon(FluentIcon.DOWNLOAD)
install_button.setFixedSize(100, 36)
install_button.clicked.connect(self.install_app)
button_layout.addWidget(refresh_button)
button_layout.addWidget(install_button)
self.scroll_layout.addWidget(button_card)
def install_app(self):
"""安装应用"""
from qfluentwidgets import InfoBar
from PyQt5.QtWidgets import QMessageBox, QProgressDialog
# 检查是否有应用数据
if not hasattr(self, 'app_data'):
InfoBar.error(
title="错误",
content="应用数据未加载,请刷新页面后重试。",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP,
parent=self
)
return
# 创建确认对话框
reply = QMessageBox.question(self,
"确认安装",
f"您确定要安装{self.app_data.get('name', '未知应用')}吗?\n\n点击'确定'开始安装。",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No)
if reply == QMessageBox.Yes:
# 显示开始安装的提示
InfoBar.success(
title="安装开始",
content=f"{self.app_data.get('name', '未知应用')}安装已开始,请稍候...",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP,
duration=3000,
parent=self
)
# 获取下载链接(使用应用数据中的直链下载地址)
download_url = self.app_data.get('direct_download_url')
# 如果没有直接下载链接则尝试使用备用的download_url字段
if not download_url:
download_url = self.app_data.get('download_url')
# 如果仍然没有下载链接,显示错误信息
if not download_url:
InfoBar.error(
title="错误",
content="无法获取应用的下载链接,请稍后重试。",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP,
parent=self
)
return
# 创建进度对话框
self.progress_dialog = QProgressDialog(
f"正在下载{self.app_data.get('name', '未知应用')}...",
"取消",
0,
100,
parent=self
)
self.progress_dialog.setWindowTitle("正在安装")
self.progress_dialog.setMinimumDuration(0)
# 创建临时保存路径
file_extension = ".exe" # 假设是Windows可执行文件
app_name = self.app_data.get('name', '未知应用').replace(' ', '_')
temp_dir = tempfile.gettempdir()
save_path = os.path.join(temp_dir, f"{app_name}_installer{file_extension}")
# 创建下载线程
self.download_thread = DownloadThread(download_url, save_path)
self.download_thread.progress.connect(self.progress_dialog.setValue)
self.download_thread.finished.connect(self.on_download_finished)
self.download_thread.error.connect(self.on_download_error)
# 开始下载
self.download_thread.start()
self.progress_dialog.exec_()
def on_download_finished(self, file_path):
"""下载完成处理"""
self.progress_dialog.accept()
# 根据操作系统执行不同的安装操作
if platform.system() == "Windows":
try:
# 在Windows上直接运行可执行文件
subprocess.Popen([file_path], shell=True)
# 显示安装成功提示
InfoBar.success(
title="下载完成",
content=f"安装程序已启动,请按照向导完成安装。\n文件位置:{file_path}",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP,
duration=5000,
parent=self
)
except Exception as e:
InfoBar.error(
title="启动安装程序失败",
content=f"无法启动安装程序: {str(e)}\n您可以手动运行文件: {file_path}",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP,
parent=self
)
else:
# 其他操作系统
InfoBar.information(
title="下载完成",
content=f"文件已下载完成。\n\n文件位置:{file_path}\n\n请手动运行安装程序。",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP,
duration=5000,
parent=self
)
def on_download_error(self, error_msg):
"""下载错误处理"""
self.progress_dialog.reject()
InfoBar.error(
title="安装失败",
content=error_msg,
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP,
parent=self
)
def share_app(self):
"""分享应用"""
from qfluentwidgets import InfoBar, PushButton
from PyQt5.QtGui import QClipboard
from PyQt5.QtWidgets import QApplication, QMessageBox
import webbrowser
# 创建分享链接
app_share_url = f"leonapp://app/{self.app_id}"
web_share_url = f"http://leonmcoset.jjxmm.win:8010/app?id={self.app_id}"
# 创建自定义对话框
dialog = QMessageBox(self)
dialog.setWindowTitle("分享应用")
dialog.setText(f"请选择分享方式:\n\n{self.app_data.get('name', '未知应用')}")
dialog.setIcon(QMessageBox.Information)
# 添加按钮
copy_web_url_btn = dialog.addButton("复制网页链接", QMessageBox.AcceptRole)
share_wechat_btn = dialog.addButton("分享到微信", QMessageBox.RejectRole)
copy_app_url_btn = dialog.addButton("复制应用内链接", QMessageBox.ActionRole)
# 显示对话框并处理结果
dialog.exec_()
clicked_button = dialog.clickedButton()
if clicked_button == copy_web_url_btn:
# 复制网页链接
self.copy_to_clipboard(web_share_url)
elif clicked_button == share_wechat_btn:
# 分享到微信(模拟功能)
InfoBar.info(
title="分享到微信",
content="请将以下链接分享给微信好友:\n" + web_share_url,
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP,
duration=5000,
parent=self
)
self.copy_to_clipboard(web_share_url)
elif clicked_button == copy_app_url_btn:
# 复制应用内链接
self.copy_to_clipboard(app_share_url)
def copy_to_clipboard(self, text):
"""复制文本到剪贴板"""
from qfluentwidgets import InfoBar
clipboard = QApplication.clipboard()
clipboard.setText(text)
InfoBar.success(
title="复制成功",
content="链接已复制到剪贴板!",
orient=Qt.Horizontal,
isClosable=True,
position=InfoBarPosition.TOP,
duration=2000,
parent=self
)
def closeEvent(self, event):
"""关闭窗口事件"""
# 如果需要在关闭时执行清理操作,可以在这里添加
event.accept()