更新
This commit is contained in:
@@ -10,13 +10,12 @@ from datetime import date, datetime
|
||||
from typing import Any
|
||||
|
||||
from PySide6.QtCore import QObject, QRunnable, Qt, QThreadPool, QTimer, Signal, Slot
|
||||
from PySide6.QtGui import QResizeEvent
|
||||
from PySide6.QtGui import QColor, QPainter, QPaintEvent, QResizeEvent
|
||||
from PySide6.QtWidgets import (
|
||||
QAbstractItemView,
|
||||
QFrame,
|
||||
QHBoxLayout,
|
||||
QLabel,
|
||||
QProgressBar,
|
||||
QPushButton,
|
||||
QSizePolicy,
|
||||
QTableWidget,
|
||||
@@ -543,30 +542,74 @@ def show_toast(parent: QWidget, text: str, kind: str = "info", duration: int = 2
|
||||
toast.show_message(text, kind, duration)
|
||||
|
||||
|
||||
class _BusyTrack(QWidget):
|
||||
"""Indeterminate bar painted in-process, without Windows QProgressBar HWNDs.
|
||||
|
||||
``QProgressBar.setRange(0, 0)`` uses the native Vista/Win11 animation, which
|
||||
creates extra untitled windows titled with the application name.
|
||||
"""
|
||||
|
||||
def __init__(self, parent: QWidget) -> None:
|
||||
super().__init__(parent)
|
||||
self.setObjectName("BusyOverlayProgress")
|
||||
self.setFixedSize(140, 6)
|
||||
self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
|
||||
self._phase = 0.0
|
||||
self._timer = QTimer(self)
|
||||
self._timer.setInterval(32)
|
||||
self._timer.timeout.connect(self._tick)
|
||||
|
||||
def showEvent(self, event: Any) -> None:
|
||||
self._timer.start()
|
||||
super().showEvent(event)
|
||||
|
||||
def hideEvent(self, event: Any) -> None:
|
||||
self._timer.stop()
|
||||
super().hideEvent(event)
|
||||
|
||||
def _tick(self) -> None:
|
||||
self._phase = (self._phase + 0.035) % 1.0
|
||||
self.update()
|
||||
|
||||
def paintEvent(self, event: QPaintEvent) -> None: # noqa: N802 - Qt API
|
||||
del event
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||
painter.setPen(Qt.PenStyle.NoPen)
|
||||
rect = self.rect()
|
||||
painter.setBrush(QColor("#D8DEEA"))
|
||||
painter.drawRoundedRect(rect, 3, 3)
|
||||
chunk_width = max(36, int(rect.width() * 0.32))
|
||||
span = rect.width() + chunk_width
|
||||
x = int(self._phase * span) - chunk_width
|
||||
painter.setBrush(QColor("#4F63D9"))
|
||||
painter.drawRoundedRect(x, 0, chunk_width, rect.height(), 3, 3)
|
||||
|
||||
|
||||
class BusyOverlay(QFrame):
|
||||
"""Non-blocking visual guard for a card or page while a worker is active."""
|
||||
|
||||
def __init__(self, parent: QWidget, text: str = "正在加载…") -> None:
|
||||
super().__init__(parent)
|
||||
self.setObjectName("BusyOverlay")
|
||||
self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
layout.setSpacing(10)
|
||||
self.label = QLabel(text)
|
||||
self.label = QLabel(text, self)
|
||||
self.label.setProperty("role", "muted")
|
||||
progress = QProgressBar()
|
||||
progress.setObjectName("BusyOverlayProgress")
|
||||
progress.setRange(0, 0)
|
||||
progress.setFixedWidth(140)
|
||||
self.progress = _BusyTrack(self)
|
||||
layout.addWidget(self.label, 0, Qt.AlignmentFlag.AlignCenter)
|
||||
layout.addWidget(progress, 0, Qt.AlignmentFlag.AlignCenter)
|
||||
layout.addWidget(self.progress, 0, Qt.AlignmentFlag.AlignCenter)
|
||||
self.hide()
|
||||
|
||||
def set_message(self, text: str) -> None:
|
||||
self.label.setText(text)
|
||||
|
||||
def showEvent(self, event: Any) -> None:
|
||||
self.setGeometry(self.parentWidget().rect())
|
||||
parent = self.parentWidget()
|
||||
if parent is not None:
|
||||
self.setGeometry(parent.rect())
|
||||
self.raise_()
|
||||
super().showEvent(event)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user