Source code for editor.widgets.misc.toast

from PySide6.QtCore import Qt, QTimer, QEvent, Property, QPropertyAnimation
from PySide6.QtGui import QFont, QPainter, QColor, QBrush
from PySide6.QtWidgets import QWidget
from editor.common.math import lerpI, clamp

_toastFont = QFont('consolas', 13)

[docs]class Toast(QWidget): def __init__(self, parent, msg, duration = 2000): super(Toast, self).__init__(parent) self.msg = msg self.duration = duration self._alpha = 220 QTimer.singleShot(self.duration, self.fadeToast) parent.installEventFilter(self) self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.SubWindow) self.setAttribute(Qt.WA_TransparentForMouseEvents, True) self.setAttribute(Qt.WA_TranslucentBackground, True) self.setAttribute(Qt.WA_DeleteOnClose, True) # self.setAttribute(Qt.WA_TranslucentBackground | Qt.WA_DeleteOnClose) self.moveCenter() @Property(int)
[docs] def alpha(self): return self._alpha
@alpha.setter def alpha(self, value): self._alpha = value self.update()
[docs] def fadeToast(self): self.anim = QPropertyAnimation(self, b'alpha') self.anim.finished.connect(self.onFadeFinish) self.anim.setStartValue(self._alpha) self.anim.setDuration(800) self.anim.setEndValue(0) self.anim.start()
[docs] def onFadeFinish(self): self.anim.deleteLater() self.parent().removeEventFilter(self) self.close()
[docs] def eventFilter(self, obj, e): if e.type() == QEvent.Resize: self.moveCenter() return False
[docs] def paintEvent(self, a0): rect = self.rect() painter = QPainter() painter.begin(self) painter.setRenderHints(QPainter.Antialiasing, True) painter.setBrush(QBrush(QColor(100, 100, 100, self._alpha))) painter.setPen(Qt.transparent) painter.drawRoundedRect(rect, 15, 15) painter.setPen(QColor(230, 230, 230, self._alpha)) painter.setFont(_toastFont) painter.drawText(rect, Qt.AlignCenter, self.msg) painter.end()
[docs] def moveCenter(self): rect = self.parent().rect() pw, ph = rect.width(), rect.height() sw = clamp(pw * 0.7, 100, 400) sh = clamp(ph * 0.4, 40 , 160) self.setFixedSize(sw, sh) offsetToBottom = ph * 0.15 xPos = int((pw - sw)/2) yPos = int(ph - sh - offsetToBottom) self.move(xPos, yPos)
[docs]def notifyToast(host, msg, duration): toast = Toast(host, msg, duration) toast.show() return toast