Files
leonapp/pyqt5fluentdesign/app_detail_window.py
Leonmmcoset f0105ce819 feat: 优化应用详情和公告详情窗口的UI设计
重构应用详情窗口和公告详情窗口的UI布局,使用Fluent Design风格组件
添加卡片式布局和滚动区域,改进视觉层次和用户体验
更新主页应用列表为卡片式展示,增加点击查看详情功能
2025-09-22 22:24:56 +08:00

231 lines
8.3 KiB
Python

from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QPushButton)
from PyQt5.QtCore import Qt
from qfluentwidgets import (InfoBar, InfoBarPosition, TitleLabel, SubtitleLabel,
PrimaryPushButton, PushButton, ScrollArea, CardWidget,
FluentIcon, SimpleCardWidget, BodyLabel)
import json
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(800, 600)
self.setObjectName("AppDetailWindow")
# 添加全局样式
self.setStyleSheet("""
#AppDetailWindow {
background-color: #F2F3F5;
}
""")
# 创建中心部件
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
# 创建主布局
self.main_layout = QVBoxLayout(self.central_widget)
self.main_layout.setContentsMargins(20, 20, 20, 20)
self.main_layout.setSpacing(12)
# 创建标题区域
self.header_layout = QHBoxLayout()
self.app_title = TitleLabel("加载中...")
self.app_title.setObjectName("AppTitle")
self.close_button = PushButton("关闭")
self.close_button.clicked.connect(self.close)
self.close_button.setFixedWidth(80)
self.header_layout.addWidget(self.app_title)
self.header_layout.addStretch()
self.header_layout.addWidget(self.close_button)
# 创建滚动区域 - 使用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: transparent;
border: none;
}
QScrollBar:vertical {
width: 8px;
background: transparent;
}
QScrollBar::handle:vertical {
background: rgba(142, 142, 147, 0.3);
border-radius: 4px;
min-height: 40px;
}
QScrollBar::handle:vertical:hover {
background: rgba(142, 142, 147, 0.5);
}
""")
# 创建滚动内容部件
self.scroll_content = QWidget()
self.scroll_content.setObjectName("ScrollContent")
self.scroll_layout = QVBoxLayout(self.scroll_content)
self.scroll_layout.setContentsMargins(0, 0, 0, 20)
self.scroll_layout.setSpacing(16)
# 添加滚动区域到主布局
self.scroll_area.setWidget(self.scroll_content)
# 将标题区域和滚动区域添加到主布局
self.main_layout.addLayout(self.header_layout)
self.main_layout.addWidget(self.scroll_area)
# 加载应用详情
self.load_app_detail()
def load_app_detail(self):
"""加载应用详情"""
try:
# 这里应该调用API获取应用详情
# 暂时使用模拟数据
app_data = {
"id": self.app_id,
"name": "示例应用",
"description": "这是一个示例应用,用于展示应用详情页面",
"developer_id": "1",
"developer_name": "示例开发者",
"status": "approved",
"version": "1.0.0",
"created_at": "2023-01-01 10:00:00"
}
# 更新窗口标题
self.setWindowTitle(f"应用详情 - {app_data.get('name', '未知应用')}")
self.app_title.setText(app_data.get('name', '未知应用'))
# 清空滚动区域
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_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_app_info_card(self, app_data):
"""显示应用基本信息卡片"""
info_card = CardWidget()
info_card.setObjectName("InfoCard")
card_layout = QVBoxLayout(info_card)
card_layout.setContentsMargins(16, 16, 16, 16)
card_layout.setSpacing(12)
# 卡片标题
card_title = SubtitleLabel("基本信息")
card_layout.addWidget(card_title)
# 信息网格布局
info_grid_layout = QVBoxLayout()
info_grid_layout.setSpacing(6)
# 添加基本信息字段
info_items = [
("应用ID", app_data.get("id", "--")),
("开发者", app_data.get("developer_name", "--")),
("状态", app_data.get("status", "--")),
("当前版本", app_data.get("version", "--")),
("创建时间", app_data.get("created_at", "--"))
]
for label_text, value_text in info_items:
info_row = QHBoxLayout()
# 标签和值之间的比例
info_row.addWidget(BodyLabel(f"{label_text}:"), 1)
info_row.addWidget(BodyLabel(f"{value_text}"), 3)
info_grid_layout.addLayout(info_row)
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")
card_layout = QVBoxLayout(description_card)
card_layout.setContentsMargins(16, 16, 16, 16)
card_layout.setSpacing(12)
# 卡片标题
card_title = SubtitleLabel("应用描述")
card_layout.addWidget(card_title)
# 描述文本
from qfluentwidgets import TextEdit
description_text = TextEdit()
description_text.setReadOnly(True)
description_text.setWordWrapMode(3) # QTextOption.WrapAtWordBoundaryOrAnywhere
description_text.setMinimumHeight(150)
description_text.setStyleSheet("""
TextEdit {
background-color: transparent;
border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 6px;
padding: 8px;
}
""")
# 设置描述内容
description_text.setPlainText(app_data.get("description", "无描述信息"))
card_layout.addWidget(description_text)
self.scroll_layout.addWidget(description_card)
def display_action_buttons(self):
"""显示操作按钮区域"""
button_card = SimpleCardWidget()
button_card.setObjectName("ButtonCard")
button_card.setMinimumHeight(80)
button_layout = QHBoxLayout(button_card)
button_layout.setContentsMargins(16, 16, 16, 16)
button_layout.addStretch()
# 刷新按钮
refresh_button = PushButton("刷新")
refresh_button.setIcon(FluentIcon.SYNC)
refresh_button.clicked.connect(self.load_app_detail)
button_layout.addWidget(refresh_button)
self.scroll_layout.addWidget(button_card)
def closeEvent(self, event):
"""关闭窗口事件"""
# 如果需要在关闭时执行清理操作,可以在这里添加
event.accept()