feat: 优化应用详情和公告详情窗口的UI设计

重构应用详情窗口和公告详情窗口的UI布局,使用Fluent Design风格组件
添加卡片式布局和滚动区域,改进视觉层次和用户体验
更新主页应用列表为卡片式展示,增加点击查看详情功能
This commit is contained in:
2025-09-22 22:24:56 +08:00
parent 4236caaf33
commit f0105ce819
82 changed files with 432 additions and 4834 deletions

View File

@@ -1,8 +1,9 @@
from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QPushButton, QTextEdit, QGroupBox, QFormLayout, QScrollArea)
QPushButton)
from PyQt5.QtCore import Qt
from qfluentwidgets import (InfoBar, InfoBarPosition, TitleLabel, SubtitleLabel,
PrimaryPushButton, PushButton)
PrimaryPushButton, PushButton, ScrollArea, CardWidget,
FluentIcon, SimpleCardWidget, BodyLabel)
import json
class AppDetailWindow(QMainWindow):
@@ -15,6 +16,14 @@ class AppDetailWindow(QMainWindow):
# 设置窗口属性
self.setWindowTitle("应用详情")
self.resize(800, 600)
self.setObjectName("AppDetailWindow")
# 添加全局样式
self.setStyleSheet("""
#AppDetailWindow {
background-color: #F2F3F5;
}
""")
# 创建中心部件
self.central_widget = QWidget()
@@ -22,28 +31,59 @@ class AppDetailWindow(QMainWindow):
# 创建主布局
self.main_layout = QVBoxLayout(self.central_widget)
self.main_layout.setContentsMargins(20, 20, 20, 20)
self.main_layout.setSpacing(12)
# 创建标题区域
self.title_layout = QHBoxLayout()
self.title_label = TitleLabel("应用详情")
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.title_layout.addWidget(self.title_label)
self.title_layout.addStretch()
self.title_layout.addWidget(self.close_button)
self.header_layout.addWidget(self.app_title)
self.header_layout.addStretch()
self.header_layout.addWidget(self.close_button)
# 创建滚动区域
self.scroll_area = QScrollArea()
# 创建滚动区域 - 使用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.title_layout)
self.main_layout.addLayout(self.header_layout)
self.main_layout.addWidget(self.scroll_area)
# 加载应用详情
@@ -65,6 +105,10 @@ class AppDetailWindow(QMainWindow):
"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()
@@ -72,13 +116,13 @@ class AppDetailWindow(QMainWindow):
widget.setParent(None)
widget.deleteLater()
# 显示应用基本信息
self.display_app_info(app_data)
# 显示应用基本信息卡片
self.display_app_info_card(app_data)
# 显示应用描述
self.display_app_description(app_data)
# 显示应用描述卡片
self.display_description_card(app_data)
# 显示操作按钮
# 显示操作按钮区域
self.display_action_buttons()
except Exception as e:
@@ -92,49 +136,94 @@ class AppDetailWindow(QMainWindow):
parent=self
)
def display_app_info(self, app_data):
"""显示应用基本信息"""
info_group = QGroupBox("基本信息")
info_layout = QFormLayout()
def display_app_info_card(self, app_data):
"""显示应用基本信息卡片"""
info_card = CardWidget()
info_card.setObjectName("InfoCard")
# 设置表单布局标签对齐
info_layout.setLabelAlignment(Qt.AlignRight | Qt.AlignVCenter)
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_layout.addRow("应用ID:", QLabel(app_data.get("id", "--")))
info_layout.addRow("应用名称:", QLabel(app_data.get("name", "--")))
info_layout.addRow("开发者ID:", QLabel(app_data.get("developer_id", "--")))
info_layout.addRow("开发者名称:", QLabel(app_data.get("developer_name", "--")))
info_layout.addRow("应用状态:", QLabel(app_data.get("status", "--")))
info_layout.addRow("当前版本:", QLabel(app_data.get("version", "--")))
info_layout.addRow("创建时间:", QLabel(app_data.get("created_at", "--")))
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", "--"))
]
info_group.setLayout(info_layout)
self.scroll_layout.addWidget(info_group)
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_app_description(self, app_data):
"""显示应用描述"""
description_group = QGroupBox("应用描述")
description_layout = QVBoxLayout()
def display_description_card(self, app_data):
"""显示应用描述卡片"""
description_card = CardWidget()
description_card.setObjectName("DescriptionCard")
description_text = QTextEdit()
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", "无描述信息"))
description_layout.addWidget(description_text)
description_group.setLayout(description_layout)
self.scroll_layout.addWidget(description_group)
card_layout.addWidget(description_text)
self.scroll_layout.addWidget(description_card)
def display_action_buttons(self):
"""显示操作按钮"""
buttons_layout = QHBoxLayout()
buttons_layout.addStretch()
"""显示操作按钮区域"""
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)
buttons_layout.addWidget(refresh_button)
self.scroll_layout.addLayout(buttons_layout)
button_layout.addWidget(refresh_button)
self.scroll_layout.addWidget(button_card)
def closeEvent(self, event):
"""关闭窗口事件"""

View File

@@ -6,7 +6,7 @@ LeonApp GUI - 基于PyQt5和Fluent Design的App Store API图形界面工具
"""
# APP版本号
APP_VERSION = "Beta 0.2"
APP_VERSION = "Beta 0.3"
import sys
import json
@@ -18,17 +18,18 @@ import markdown
from enum import Enum
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QTabWidget, QWidget, QVBoxLayout, QHBoxLayout,
QTableWidgetItem, QTableWidget, QTextEdit, QFrame, QHeaderView
QTableWidgetItem, QTableWidget, QTextEdit, QFrame, QHeaderView, QLabel
)
from PyQt5.QtGui import QTextOption
from PyQt5.QtCore import Qt, pyqtSignal, QThread
from qfluentwidgets import (
CardWidget, TitleLabel, SubtitleLabel, CaptionLabel, PushButton,
CardWidget, TitleLabel, SubtitleLabel, CaptionLabel, BodyLabel, PushButton,
PrimaryPushButton, LineEdit, ComboBox, ProgressBar, TableWidget,
ScrollArea, InfoBar, InfoBarPosition, NavigationInterface, NavigationItemPosition,
FluentWindow, FluentIcon
FluentWindow, FluentIcon, SimpleCardWidget
)
from qfluentwidgets import FluentTranslator
from app_detail_window import AppDetailWindow
class APIClient:
"""API客户端类处理与API的通信"""
@@ -122,14 +123,43 @@ class HomepageTab(QWidget):
apps_layout = QVBoxLayout(self.latest_apps_card)
apps_layout.setContentsMargins(20, 20, 20, 20)
# 创建最新应用表格
self.latest_apps_table = TableWidget()
self.latest_apps_table.setColumnCount(4)
self.latest_apps_table.setHorizontalHeaderLabels(["ID", "应用名称", "版本", "添加时间"])
self.latest_apps_table.horizontalHeader().setSectionResizeMode(1, 3)
self.latest_apps_table.cellDoubleClicked.connect(self.show_app_detail)
self.latest_apps_table.setMaximumHeight(250)
apps_layout.addWidget(self.latest_apps_table)
# 创建水平滚动区域来放置应用卡片 - 设置为隐形样式
self.apps_scroll_area = ScrollArea()
self.apps_scroll_area.setWidgetResizable(True)
self.apps_scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.apps_scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# 设置隐形样式
self.apps_scroll_area.setStyleSheet("""
QScrollArea {
background-color: transparent;
border: none;
}
QScrollArea > QWidget > QWidget {
background-color: transparent;
}
QScrollBar:horizontal {
height: 0px;
background: transparent;
}
QScrollBar::handle:horizontal {
background: transparent;
min-width: 0px;
}
""")
# 创建水平布局来放置卡片
self.apps_container = QWidget()
self.apps_layout = QHBoxLayout(self.apps_container)
self.apps_layout.setContentsMargins(0, 0, 0, 0)
self.apps_layout.setSpacing(15)
# 设置滚动区域的内容
self.apps_scroll_area.setWidget(self.apps_container)
self.apps_scroll_area.setMaximumHeight(1000)
self.apps_scroll_area.setMaximumWidth(1000)
self.apps_scroll_area.setMinimumWidth(1000)
apps_layout.addWidget(self.apps_scroll_area)
@@ -152,11 +182,30 @@ class HomepageTab(QWidget):
self.latest_announcements_list_layout = QVBoxLayout(self.latest_announcements_list)
self.latest_announcements_list_layout.setContentsMargins(0, 0, 0, 0)
# 创建滚动区域放置公告列表
# 创建滚动区域放置公告列表 - 设置为隐形样式
scroll_area = ScrollArea()
scroll_area.setWidgetResizable(True)
# 设置隐形样式
scroll_area.setStyleSheet("""
QScrollArea {
background-color: transparent;
border: none;
}
QScrollArea > QWidget > QWidget {
background-color: transparent;
}
QScrollBar:vertical {
width: 0px;
background: transparent;
}
QScrollBar::handle:vertical {
background: transparent;
min-height: 0px;
}
""")
scroll_area.setWidget(self.latest_announcements_list)
scroll_area.setMaximumHeight(250)
scroll_area.setMaximumHeight(300)
announcements_layout.addWidget(scroll_area)
@@ -199,25 +248,118 @@ class HomepageTab(QWidget):
def on_latest_apps_loaded(self, data):
"""最新应用加载完成处理"""
# 清空表格
self.latest_apps_table.setRowCount(0)
# 清空现有卡片
while self.apps_layout.count() > 0:
item = self.apps_layout.takeAt(0)
widget = item.widget()
if widget:
widget.deleteLater()
if data and isinstance(data, dict) and 'apps' in data and isinstance(data['apps'], list):
# 填充表格
# 为每个应用创建卡片
index = 0
for app in data['apps']:
if not isinstance(app, dict):
continue
# 只显示前三个应用
if index >= 3:
break
index += 1
row_pos = self.latest_apps_table.rowCount()
self.latest_apps_table.insertRow(row_pos)
# 创建卡片 - 微软商店风格
app_card = CardWidget()
app_card.setFixedWidth(160) # 固定卡片宽度
app_card.setFixedHeight(220) # 固定卡片高度
# 使用样式表设置圆角并移除边框
app_card.setStyleSheet("""
QWidget {
border-radius: 12px;
border: none;
}
""")
self.latest_apps_table.setItem(row_pos, 0, QTableWidgetItem(str(app.get('id', ''))))
self.latest_apps_table.setItem(row_pos, 1, QTableWidgetItem(app.get('name', '')))
self.latest_apps_table.setItem(row_pos, 2, QTableWidgetItem(app.get('version', '')))
self.latest_apps_table.setItem(row_pos, 3, QTableWidgetItem(app.get('created_at', '')))
# 创建卡片内容布局
card_layout = QVBoxLayout(app_card)
card_layout.setContentsMargins(12, 12, 12, 12)
card_layout.setSpacing(8) # 调整间距
# 添加应用ID隐藏
app_id_label = QLabel(str(app.get('id', '')))
app_id_label.setVisible(False)
card_layout.addWidget(app_id_label)
# 添加应用图标占位区 - 微软商店风格的图标位置
icon_widget = QWidget()
icon_widget.setFixedSize(100, 100)
icon_layout = QVBoxLayout(icon_widget)
icon_layout.setAlignment(Qt.AlignCenter)
# 创建图标占位符(实际应用中可以替换为真实图标)
placeholder_label = QLabel()
placeholder_label.setFixedSize(80, 80)
placeholder_label.setStyleSheet("""
background-color: #f0f0f0;
border-radius: 12px;
font-size: 32px;
color: #666;
""")
placeholder_label.setAlignment(Qt.AlignCenter)
# 使用应用名称的第一个字符作为图标占位符
first_char = app.get('name', 'A')[0].upper() if app.get('name') else 'A'
placeholder_label.setText(first_char)
icon_layout.addWidget(placeholder_label)
card_layout.addWidget(icon_widget, alignment=Qt.AlignCenter)
# 添加应用名称 - 限制为2行
name_label = SubtitleLabel(app.get('name', '无名称'))
name_label.setWordWrap(True)
name_label.setMaximumHeight(40) # 限制高度最多显示2行
name_label.setStyleSheet("""
QLabel {
font-weight: 500;
font-size: 14px;
}
""")
card_layout.addWidget(name_label)
# 添加应用版本和添加时间(合并显示)
version = app.get('version', '未知')
created_at = app.get('created_at', '未知')
# 简化时间显示
if created_at != '未知':
try:
# 假设时间格式为ISO格式提取日期部分
if 'T' in created_at:
created_at = created_at.split('T')[0]
except:
pass
info_label = CaptionLabel(f"版本 {version} · {created_at}")
info_label.setStyleSheet("""
QLabel {
color: #666;
font-size: 12px;
}
""")
card_layout.addWidget(info_label)
# 添加获取按钮(模拟微软商店的获取按钮)- 使用PrimaryPushButton获得标准的蓝色按钮
get_button = PrimaryPushButton("查看详情")
get_button.setFixedHeight(32)
get_button.clicked.connect(lambda checked, app_id=app.get('id', ''): self.show_app_detail(app_id))
card_layout.addWidget(get_button)
# 添加点击事件到整个卡片
app_card.mousePressEvent = lambda event, app_id=app.get('id', ''): self.show_app_detail(app_id)
# 将卡片添加到水平布局
self.apps_layout.addWidget(app_card)
# 自动调整列宽
self.latest_apps_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
# 添加一个占位符,确保卡片不会被拉伸
self.apps_layout.addStretch()
# 检查是否还有其他数据正在加载
if not self.apps_worker.isRunning() and not self.announcements_worker.isRunning():
@@ -290,12 +432,11 @@ class HomepageTab(QWidget):
if not self.apps_worker.isRunning() and not self.announcements_worker.isRunning():
self.hide_progress()
def show_app_detail(self, row, column):
def show_app_detail(self, app_id):
"""显示应用详情"""
app_id = self.latest_apps_table.item(row, 0).text()
# 调用父窗口的show_app_detail方法
if hasattr(self.parent(), 'show_app_detail'):
self.parent().show_app_detail(app_id)
# 直接创建并显示应用详情窗口
detail_window = AppDetailWindow(self.api_client, app_id, self)
detail_window.show()
def show_announcement_detail(self, announcement_id):
"""显示公告详情方法已被移除,现在主页直接显示最新公告内容"""
@@ -1552,12 +1693,22 @@ class AppDetailWindow(QMainWindow):
description_label = SubtitleLabel("描述")
self.info_layout.addWidget(description_label)
# 使用QTextEdit替代CaptionLabel以支持富文本显示
description_text = QTextEdit()
# 使用QFluentWidgets的TextEdit支持Markdown显示
from qfluentwidgets import TextEdit
description_text = TextEdit()
description_text.setReadOnly(True)
description_text.setWordWrapMode(QTextOption.WrapAtWordBoundaryOrAnywhere)
description_text.setLineWrapMode(QTextEdit.WidgetWidth)
description_text.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
# 设置Fluent风格
description_text.setStyleSheet("""
TextEdit {
background-color: transparent;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 6px;
padding: 8px;
}
""")
# 尝试将markdown格式的描述转换为HTML
app_description = data.get('description', '暂无描述')
@@ -1982,6 +2133,18 @@ class AnnouncementDetailWindow(QMainWindow):
self.title = title
self.created_at = created_at
# 设置窗口属性
self.setWindowTitle(f"公告详情 - {title}")
self.resize(700, 550)
self.setObjectName("AnnouncementDetailWindow")
# 添加全局样式
self.setStyleSheet("""
#AnnouncementDetailWindow {
background-color: #F2F3F5;
}
""")
# 将Markdown内容转换为HTML
try:
import markdown
@@ -1992,8 +2155,6 @@ class AnnouncementDetailWindow(QMainWindow):
print(f"Markdown转换失败: {str(e)}")
self.content = content
self.setWindowTitle(f"公告详情 - {title}")
self.resize(600, 500)
self.init_ui()
def init_ui(self):
@@ -2005,15 +2166,66 @@ class AnnouncementDetailWindow(QMainWindow):
# 创建主布局
main_layout = QVBoxLayout(central_widget)
main_layout.setContentsMargins(20, 20, 20, 20)
main_layout.setSpacing(12)
# 创建标题
title_label = TitleLabel(f"{self.title}")
main_layout.addWidget(title_label)
self.title_label = TitleLabel(f"{self.title}")
self.title_label.setObjectName("AnnouncementTitle")
main_layout.addWidget(self.title_label)
# 创建滚动区域 - 使用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_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)
main_layout.addWidget(self.scroll_area)
# 创建信息卡片
self.info_card = CardWidget()
self.info_layout = QVBoxLayout(self.info_card)
main_layout.addWidget(self.info_card)
self.create_info_card()
# 创建内容卡片
self.create_content_card()
# 添加关闭按钮
self.create_close_button(main_layout)
def create_info_card(self):
"""创建公告信息卡片"""
info_card = SimpleCardWidget()
info_card.setObjectName("InfoCard")
card_layout = QHBoxLayout(info_card)
card_layout.setContentsMargins(16, 12, 16, 12)
card_layout.setSpacing(20)
# 添加公告信息
info_items = [
@@ -2022,33 +2234,68 @@ class AnnouncementDetailWindow(QMainWindow):
]
for label_text, value_text in info_items:
label = CaptionLabel(f"{label_text}: {value_text}")
self.info_layout.addWidget(label)
info_layout = QVBoxLayout()
label = CaptionLabel(label_text)
value = BodyLabel(value_text)
info_layout.addWidget(label)
info_layout.addWidget(value)
card_layout.addLayout(info_layout)
# 添加分隔线
separator = QWidget()
separator.setMinimumHeight(10)
self.info_layout.addWidget(separator)
card_layout.addStretch()
self.scroll_layout.addWidget(info_card)
def create_content_card(self):
"""创建公告内容卡片"""
content_card = CardWidget()
content_card.setObjectName("ContentCard")
card_layout = QVBoxLayout(content_card)
card_layout.setContentsMargins(16, 16, 16, 16)
card_layout.setSpacing(12)
# 添加内容标题
content_title = SubtitleLabel("公告内容")
self.info_layout.addWidget(content_title)
card_layout.addWidget(content_title)
# 添加内容文本框支持Markdown渲染
self.content_text = QTextEdit()
from qfluentwidgets import TextEdit
self.content_text = TextEdit()
self.content_text.setHtml(self.content_html)
self.content_text.setReadOnly(True)
self.content_text.setMinimumHeight(200)
self.content_text.setMinimumHeight(250)
self.content_text.setLineWrapMode(QTextEdit.WidgetWidth)
self.content_text.setWordWrapMode(QTextOption.WrapAtWordBoundaryOrAnywhere)
self.info_layout.addWidget(self.content_text)
# 添加关闭按钮
button_layout = QHBoxLayout()
# 设置Fluent风格样式
self.content_text.setStyleSheet("""
TextEdit {
background-color: transparent;
border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 6px;
padding: 12px;
}
""")
card_layout.addWidget(self.content_text)
self.scroll_layout.addWidget(content_card)
def create_close_button(self, parent_layout):
"""创建关闭按钮"""
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()
close_button = PushButton("关闭")
close_button.setFixedWidth(100)
close_button.clicked.connect(self.close)
button_layout.addWidget(close_button, alignment=Qt.AlignCenter)
main_layout.addLayout(button_layout)
button_layout.addWidget(close_button)
parent_layout.addWidget(button_card)
class DeveloperInfoWindow(QMainWindow):
"""开发者信息窗口"""

Binary file not shown.

File diff suppressed because it is too large Load Diff