refactor(gui): 移除成功浮动提示条,构建结果仅弹窗展示
This commit is contained in:
+1
-106
@@ -27,7 +27,7 @@ if sys.platform.startswith("win") and "QT_QPA_PLATFORM" not in os.environ:
|
|||||||
os.environ["QT_QPA_PLATFORM"] = "windows:fontengine=freetype"
|
os.environ["QT_QPA_PLATFORM"] = "windows:fontengine=freetype"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from PySide6.QtCore import QEasingCurve, QEvent, QPropertyAnimation, Qt, QTimer, QUrl
|
from PySide6.QtCore import QEvent, Qt, QUrl
|
||||||
from PySide6.QtGui import QDragEnterEvent, QDragMoveEvent, QDropEvent, QFont, QIcon, QIntValidator, QKeyEvent, QPixmap
|
from PySide6.QtGui import QDragEnterEvent, QDragMoveEvent, QDropEvent, QFont, QIcon, QIntValidator, QKeyEvent, QPixmap
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QApplication,
|
QApplication,
|
||||||
@@ -38,7 +38,6 @@ try:
|
|||||||
QFileDialog,
|
QFileDialog,
|
||||||
QFormLayout,
|
QFormLayout,
|
||||||
QGridLayout,
|
QGridLayout,
|
||||||
QGraphicsOpacityEffect,
|
|
||||||
QGroupBox,
|
QGroupBox,
|
||||||
QHBoxLayout,
|
QHBoxLayout,
|
||||||
QHeaderView,
|
QHeaderView,
|
||||||
@@ -133,103 +132,6 @@ def first_preview_image_member(member_names: list[str], gcode_member: str | None
|
|||||||
return sorted(candidates, key=preview_image_sort_key)[0]
|
return sorted(candidates, key=preview_image_sort_key)[0]
|
||||||
|
|
||||||
|
|
||||||
class SuccessToast(QLabel):
|
|
||||||
"""构建成功时的浮动提示条组件。
|
|
||||||
|
|
||||||
提供淡入-停留-淡出动画效果,自动居中于父窗口底部。
|
|
||||||
不会拦截鼠标事件,点击可穿透到下层控件。
|
|
||||||
"""
|
|
||||||
|
|
||||||
FADE_MS = 1000 # 淡入/淡出动画时长(毫秒)
|
|
||||||
HOLD_MS = 5000 # 停留显示时长(毫秒)
|
|
||||||
|
|
||||||
def __init__(self, parent: QWidget) -> None:
|
|
||||||
"""初始化浮动提示条,创建透明度动画和停留计时器。"""
|
|
||||||
super().__init__(parent)
|
|
||||||
self.setAlignment(Qt.AlignCenter)
|
|
||||||
self.setWordWrap(True)
|
|
||||||
self.setAttribute(Qt.WA_TransparentForMouseEvents)
|
|
||||||
self.setStyleSheet(
|
|
||||||
"""
|
|
||||||
QLabel {
|
|
||||||
background: #f4fff6;
|
|
||||||
color: #183f22;
|
|
||||||
border: 3px solid #2e7d32;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 14px 24px;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
self._opacity_effect = QGraphicsOpacityEffect(self)
|
|
||||||
self.setGraphicsEffect(self._opacity_effect)
|
|
||||||
# 淡入动画
|
|
||||||
self._fade_in = QPropertyAnimation(self._opacity_effect, b"opacity", self)
|
|
||||||
self._fade_in.setDuration(self.FADE_MS)
|
|
||||||
self._fade_in.setEasingCurve(QEasingCurve.InOutQuad)
|
|
||||||
# 淡出动画
|
|
||||||
self._fade_out = QPropertyAnimation(self._opacity_effect, b"opacity", self)
|
|
||||||
self._fade_out.setDuration(self.FADE_MS)
|
|
||||||
self._fade_out.setEasingCurve(QEasingCurve.InOutQuad)
|
|
||||||
self._fade_out.finished.connect(self.hide)
|
|
||||||
# 停留计时器
|
|
||||||
self._hold_timer = QTimer(self)
|
|
||||||
self._hold_timer.setSingleShot(True)
|
|
||||||
self._hold_timer.timeout.connect(self._start_fade_out)
|
|
||||||
# 监听父窗口大小变化,自动重新定位
|
|
||||||
parent.installEventFilter(self)
|
|
||||||
self.hide()
|
|
||||||
|
|
||||||
def show_message(self, message: str) -> None:
|
|
||||||
"""显示指定消息文本,启动淡入-停留-淡出动画序列。"""
|
|
||||||
self._hold_timer.stop()
|
|
||||||
self._fade_in.stop()
|
|
||||||
self._fade_out.stop()
|
|
||||||
self.setText(message)
|
|
||||||
self._fit_to_parent()
|
|
||||||
self._position()
|
|
||||||
self._opacity_effect.setOpacity(0.0)
|
|
||||||
self.show()
|
|
||||||
self.raise_()
|
|
||||||
self._fade_in.setStartValue(0.0)
|
|
||||||
self._fade_in.setEndValue(1.0)
|
|
||||||
self._fade_in.start()
|
|
||||||
self._hold_timer.start(self.FADE_MS + self.HOLD_MS)
|
|
||||||
|
|
||||||
def eventFilter(self, watched: object, event: QEvent) -> bool:
|
|
||||||
"""监听父窗口 Resize 事件,自动调整提示条尺寸和位置。"""
|
|
||||||
if watched is self.parentWidget() and event.type() == QEvent.Resize and self.isVisible():
|
|
||||||
self._fit_to_parent()
|
|
||||||
self._position()
|
|
||||||
return super().eventFilter(watched, event)
|
|
||||||
|
|
||||||
def _fit_to_parent(self) -> None:
|
|
||||||
"""根据父窗口宽度自适应提示条的最大宽度。"""
|
|
||||||
parent = self.parentWidget()
|
|
||||||
if parent is None:
|
|
||||||
return
|
|
||||||
self.setMaximumWidth(max(360, min(720, parent.width() - 48)))
|
|
||||||
self.adjustSize()
|
|
||||||
|
|
||||||
def _position(self) -> None:
|
|
||||||
"""将提示条定位到父窗口底部居中位置。"""
|
|
||||||
parent = self.parentWidget()
|
|
||||||
if parent is None:
|
|
||||||
return
|
|
||||||
margin = 24
|
|
||||||
x = max(margin, (parent.width() - self.width()) // 2)
|
|
||||||
y = max(margin, parent.height() - self.height() - margin)
|
|
||||||
self.move(x, y)
|
|
||||||
|
|
||||||
def _start_fade_out(self) -> None:
|
|
||||||
"""启动淡出动画,从当前透明度渐变至完全透明。"""
|
|
||||||
self._fade_out.stop()
|
|
||||||
self._fade_out.setStartValue(self._opacity_effect.opacity())
|
|
||||||
self._fade_out.setEndValue(0.0)
|
|
||||||
self._fade_out.start()
|
|
||||||
|
|
||||||
|
|
||||||
class DropTableWidget(QTableWidget):
|
class DropTableWidget(QTableWidget):
|
||||||
"""支持拖放 .3mf 文件的表格控件。
|
"""支持拖放 .3mf 文件的表格控件。
|
||||||
|
|
||||||
@@ -695,7 +597,6 @@ class MainWindow(QMainWindow):
|
|||||||
root.addWidget(self.output_group)
|
root.addWidget(self.output_group)
|
||||||
|
|
||||||
self.setCentralWidget(central)
|
self.setCentralWidget(central)
|
||||||
self.success_toast = SuccessToast(central)
|
|
||||||
|
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# 窗口事件
|
# 窗口事件
|
||||||
@@ -1371,10 +1272,6 @@ class MainWindow(QMainWindow):
|
|||||||
t("gui.log.md5", md5=result.gcode_md5),
|
t("gui.log.md5", md5=result.gcode_md5),
|
||||||
]
|
]
|
||||||
|
|
||||||
def show_success_toast(self, message: str) -> None:
|
|
||||||
"""显示构建成功的浮动提示条。"""
|
|
||||||
self.success_toast.show_message(message)
|
|
||||||
|
|
||||||
def build_output(self) -> None:
|
def build_output(self) -> None:
|
||||||
"""主构建入口:根据批处理模式分发到合并构建或独立构建。"""
|
"""主构建入口:根据批处理模式分发到合并构建或独立构建。"""
|
||||||
jobs = self.collect_jobs()
|
jobs = self.collect_jobs()
|
||||||
@@ -1397,7 +1294,6 @@ class MainWindow(QMainWindow):
|
|||||||
options = self.build_options_for_output(output_path)
|
options = self.build_options_for_output(output_path)
|
||||||
result = build_packed_3mf(jobs, options)
|
result = build_packed_3mf(jobs, options)
|
||||||
self._show_build_result_dialog(t("gui.dialog.build_result.title"), self.log_build_result(result))
|
self._show_build_result_dialog(t("gui.dialog.build_result.title"), self.log_build_result(result))
|
||||||
self.show_success_toast(t("gui.toast.combined_success"))
|
|
||||||
if self.clear_after_build_check.isChecked():
|
if self.clear_after_build_check.isChecked():
|
||||||
self.remove_all()
|
self.remove_all()
|
||||||
|
|
||||||
@@ -1442,7 +1338,6 @@ class MainWindow(QMainWindow):
|
|||||||
return
|
return
|
||||||
if all_lines:
|
if all_lines:
|
||||||
self._show_build_result_dialog(t("gui.dialog.build_result.title"), all_lines)
|
self._show_build_result_dialog(t("gui.dialog.build_result.title"), all_lines)
|
||||||
self.show_success_toast(t("gui.toast.batch_success", count=success_count))
|
|
||||||
if self.clear_after_build_check.isChecked():
|
if self.clear_after_build_check.isChecked():
|
||||||
self.remove_all()
|
self.remove_all()
|
||||||
if self.clear_after_build_check.isChecked():
|
if self.clear_after_build_check.isChecked():
|
||||||
|
|||||||
Reference in New Issue
Block a user