更新
This commit is contained in:
@@ -378,7 +378,7 @@ def friendly_error(error: Any) -> str:
|
||||
|
||||
|
||||
class PageHeader(QWidget):
|
||||
"""Consistent title, subtitle, and action area for business pages."""
|
||||
"""Reference-design page heading with breadcrumb, copy and actions."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -387,9 +387,29 @@ class PageHeader(QWidget):
|
||||
parent: QWidget | None = None,
|
||||
) -> None:
|
||||
super().__init__(parent)
|
||||
layout = QHBoxLayout(self)
|
||||
self.setObjectName("PageHeader")
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setSpacing(16)
|
||||
layout.setSpacing(8)
|
||||
|
||||
breadcrumb = QHBoxLayout()
|
||||
breadcrumb.setContentsMargins(0, 0, 0, 0)
|
||||
breadcrumb.setSpacing(7)
|
||||
home_label = QLabel("首页", self)
|
||||
home_label.setProperty("role", "breadcrumb")
|
||||
breadcrumb.addWidget(home_label)
|
||||
separator = QLabel("›", self)
|
||||
separator.setProperty("role", "breadcrumbSeparator")
|
||||
breadcrumb.addWidget(separator)
|
||||
self.breadcrumb_label = QLabel(title, self)
|
||||
self.breadcrumb_label.setProperty("role", "breadcrumbCurrent")
|
||||
breadcrumb.addWidget(self.breadcrumb_label)
|
||||
breadcrumb.addStretch(1)
|
||||
layout.addLayout(breadcrumb)
|
||||
|
||||
heading = QHBoxLayout()
|
||||
heading.setContentsMargins(0, 0, 0, 0)
|
||||
heading.setSpacing(16)
|
||||
text_layout = QVBoxLayout()
|
||||
text_layout.setSpacing(3)
|
||||
self.title_label = QLabel(title, self)
|
||||
@@ -400,10 +420,11 @@ class PageHeader(QWidget):
|
||||
self.subtitle_label.setWordWrap(True)
|
||||
self.subtitle_label.setVisible(bool(subtitle))
|
||||
text_layout.addWidget(self.subtitle_label)
|
||||
layout.addLayout(text_layout, 1)
|
||||
heading.addLayout(text_layout, 1)
|
||||
self.actions = QHBoxLayout()
|
||||
self.actions.setSpacing(8)
|
||||
layout.addLayout(self.actions)
|
||||
heading.addLayout(self.actions)
|
||||
layout.addLayout(heading)
|
||||
|
||||
def add_action(self, widget: QWidget) -> QWidget:
|
||||
self.actions.addWidget(widget)
|
||||
@@ -414,6 +435,56 @@ class PageHeader(QWidget):
|
||||
self.subtitle_label.setVisible(bool(text))
|
||||
|
||||
|
||||
class MetricCard(QFrame):
|
||||
"""Compact dashboard metric used above dense business tables."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
title: str,
|
||||
value: str = "0",
|
||||
*,
|
||||
hint: str = "",
|
||||
kind: str = "accent",
|
||||
glyph: str = "",
|
||||
parent: QWidget | None = None,
|
||||
) -> None:
|
||||
super().__init__(parent)
|
||||
self.setObjectName("MetricCard")
|
||||
self.setProperty("kind", kind)
|
||||
self.setMinimumHeight(82)
|
||||
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(16, 12, 14, 12)
|
||||
layout.setSpacing(12)
|
||||
copy = QVBoxLayout()
|
||||
copy.setSpacing(3)
|
||||
title_label = QLabel(title, self)
|
||||
title_label.setProperty("role", "metricTitle")
|
||||
copy.addWidget(title_label)
|
||||
self.value_label = QLabel(str(value), self)
|
||||
self.value_label.setProperty("role", "metricValue")
|
||||
copy.addWidget(self.value_label)
|
||||
self.hint_label = QLabel(hint, self)
|
||||
self.hint_label.setProperty("role", "metricHint")
|
||||
self.hint_label.setVisible(bool(hint))
|
||||
copy.addWidget(self.hint_label)
|
||||
layout.addLayout(copy, 1)
|
||||
self.glyph_label = QLabel(glyph, self)
|
||||
self.glyph_label.setObjectName("MetricGlyph")
|
||||
self.glyph_label.setProperty("kind", kind)
|
||||
self.glyph_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.glyph_label.setFixedSize(38, 38)
|
||||
self.glyph_label.setVisible(bool(glyph))
|
||||
layout.addWidget(self.glyph_label)
|
||||
|
||||
def set_value(self, value: Any) -> None:
|
||||
self.value_label.setText(display_text(value, "0"))
|
||||
|
||||
def set_hint(self, text: str) -> None:
|
||||
self.hint_label.setText(text)
|
||||
self.hint_label.setVisible(bool(text))
|
||||
|
||||
|
||||
class StatusBadge(QLabel):
|
||||
def __init__(
|
||||
self, text: str = "", kind: str = "neutral", parent: QWidget | None = None
|
||||
@@ -688,20 +759,22 @@ class Pager(QWidget):
|
||||
|
||||
def __init__(self, page_size: int = 20, parent: QWidget | None = None) -> None:
|
||||
super().__init__(parent)
|
||||
self.setObjectName("Pager")
|
||||
self.page = 1
|
||||
self.page_size = page_size
|
||||
self.total = 0
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(0, 4, 0, 0)
|
||||
layout.addStretch(1)
|
||||
self.summary = QLabel("共 0 条")
|
||||
self.summary.setProperty("role", "muted")
|
||||
layout.addWidget(self.summary)
|
||||
layout.addStretch(1)
|
||||
self.previous = QPushButton("上一页")
|
||||
self.previous.setProperty("variant", "ghost")
|
||||
self.previous.clicked.connect(lambda: self._request(self.page - 1))
|
||||
layout.addWidget(self.previous)
|
||||
self.page_label = QLabel("1 / 1")
|
||||
self.page_label.setObjectName("PagerActive")
|
||||
self.page_label.setMinimumWidth(58)
|
||||
self.page_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
layout.addWidget(self.page_label)
|
||||
@@ -763,6 +836,7 @@ __all__ = [
|
||||
"BusyOverlay",
|
||||
"EmptyState",
|
||||
"MessageBanner",
|
||||
"MetricCard",
|
||||
"OverlayHost",
|
||||
"PageHeader",
|
||||
"Pager",
|
||||
|
||||
Reference in New Issue
Block a user