geng
This commit is contained in:
@@ -716,6 +716,9 @@ class SortableTable(QTableWidget):
|
||||
self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
|
||||
self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
|
||||
self.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
|
||||
self.setHorizontalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
|
||||
self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
|
||||
self.setMinimumHeight(0)
|
||||
self.setSortingEnabled(True)
|
||||
self.verticalHeader().setVisible(False)
|
||||
self.horizontalHeader().setStretchLastSection(True)
|
||||
@@ -754,6 +757,105 @@ class SortableTable(QTableWidget):
|
||||
return item.data(Qt.ItemDataRole.UserRole) if item is not None else None
|
||||
|
||||
|
||||
class BusinessPager(QWidget):
|
||||
"""Compact numbered pager shared by dense business-list pages."""
|
||||
|
||||
page_changed = Signal(int)
|
||||
|
||||
def __init__(self, page_size: int = 15, parent: QWidget | None = None) -> None:
|
||||
super().__init__(parent)
|
||||
self.setObjectName("BusinessPager")
|
||||
self.setFixedHeight(42)
|
||||
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
|
||||
self.page = 1
|
||||
self.page_size = page_size
|
||||
self.total = 0
|
||||
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(16, 4, 16, 4)
|
||||
layout.setSpacing(7)
|
||||
self.summary = QLabel("共 0 条", self)
|
||||
self.summary.setProperty("role", "muted")
|
||||
layout.addWidget(self.summary)
|
||||
layout.addStretch(1)
|
||||
|
||||
self.previous = QPushButton("‹", self)
|
||||
self.previous.setProperty("variant", "ghost")
|
||||
self.previous.setAccessibleName("上一页")
|
||||
self.previous.clicked.connect(lambda: self._request(self.page - 1))
|
||||
layout.addWidget(self.previous)
|
||||
|
||||
self.pages_host = QWidget(self)
|
||||
self.pages_layout = QHBoxLayout(self.pages_host)
|
||||
self.pages_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.pages_layout.setSpacing(5)
|
||||
layout.addWidget(self.pages_host)
|
||||
|
||||
self.next = QPushButton("›", self)
|
||||
self.next.setProperty("variant", "ghost")
|
||||
self.next.setAccessibleName("下一页")
|
||||
self.next.clicked.connect(lambda: self._request(self.page + 1))
|
||||
layout.addWidget(self.next)
|
||||
|
||||
# The business contract fixes this list to one page size. A label is
|
||||
# intentionally used instead of a one-option combo box so the control
|
||||
# does not advertise an interaction that cannot change anything.
|
||||
self.page_size_label = QLabel(f"{page_size} 条/页", self)
|
||||
self.page_size_label.setProperty("pagerSize", True)
|
||||
self.page_size_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
layout.addWidget(self.page_size_label)
|
||||
|
||||
self.page_label: QPushButton | None = None
|
||||
self.update_state(1, 0)
|
||||
|
||||
@property
|
||||
def page_count(self) -> int:
|
||||
return max(1, (self.total + self.page_size - 1) // self.page_size)
|
||||
|
||||
def update_state(self, page: int, total: int) -> None:
|
||||
self.total = max(0, total)
|
||||
self.page = min(max(1, page), self.page_count)
|
||||
self.summary.setText(f"共 {self.total} 条")
|
||||
while self.pages_layout.count():
|
||||
item = self.pages_layout.takeAt(0)
|
||||
widget = item.widget()
|
||||
if widget is not None:
|
||||
widget.deleteLater()
|
||||
|
||||
count = self.page_count
|
||||
if count <= 4:
|
||||
pages: list[int | None] = list(range(1, count + 1))
|
||||
elif self.page <= 3:
|
||||
pages = [1, 2, 3, None, count]
|
||||
elif self.page >= count - 2:
|
||||
pages = [1, None, count - 2, count - 1, count]
|
||||
else:
|
||||
pages = [1, None, self.page, None, count]
|
||||
|
||||
self.page_label = None
|
||||
for number in pages:
|
||||
if number is None:
|
||||
ellipsis = QLabel("…", self.pages_host)
|
||||
ellipsis.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
ellipsis.setFixedWidth(24)
|
||||
self.pages_layout.addWidget(ellipsis)
|
||||
continue
|
||||
button = QPushButton(str(number), self.pages_host)
|
||||
button.setProperty("pagerPage", True)
|
||||
button.setProperty("active", number == self.page)
|
||||
button.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||
button.clicked.connect(lambda _checked=False, value=number: self._request(value))
|
||||
self.pages_layout.addWidget(button)
|
||||
if number == self.page:
|
||||
self.page_label = button
|
||||
self.previous.setEnabled(self.page > 1)
|
||||
self.next.setEnabled(self.page < count)
|
||||
|
||||
def _request(self, page: int) -> None:
|
||||
if 1 <= page <= self.page_count and page != self.page:
|
||||
self.page_changed.emit(page)
|
||||
|
||||
|
||||
class Pager(QWidget):
|
||||
page_changed = Signal(int)
|
||||
|
||||
@@ -833,6 +935,7 @@ def clear_layout(layout: QVBoxLayout | QHBoxLayout) -> None:
|
||||
|
||||
|
||||
__all__ = [
|
||||
"BusinessPager",
|
||||
"BusyOverlay",
|
||||
"EmptyState",
|
||||
"MessageBanner",
|
||||
|
||||
Reference in New Issue
Block a user