mask_dialog_base.py 3.1 KB
Newer Older
之一Yo's avatar
之一Yo 已提交
1
# coding:utf-8
之一Yo's avatar
之一Yo 已提交
2 3
from PyQt5.QtCore import QEasingCurve, QPropertyAnimation, Qt, QEvent
from PyQt5.QtGui import QColor, QResizeEvent
之一Yo's avatar
之一Yo 已提交
4
from PyQt5.QtWidgets import (QDialog, QGraphicsDropShadowEffect,
之一Yo's avatar
之一Yo 已提交
5 6
                             QGraphicsOpacityEffect, QHBoxLayout, QWidget, QFrame)

7
from ...common.config import isDarkTheme
之一Yo's avatar
之一Yo 已提交
8 9 10 11 12


class MaskDialogBase(QDialog):
    """ Dialog box base class with a mask """

之一Yo's avatar
之一Yo 已提交
13
    def __init__(self, parent=None):
之一Yo's avatar
之一Yo 已提交
14
        super().__init__(parent=parent)
之一Yo's avatar
之一Yo 已提交
15
        self._hBoxLayout = QHBoxLayout(self)
之一Yo's avatar
之一Yo 已提交
16 17 18
        self.windowMask = QWidget(self)

        # dialog box in the center of mask, all widgets take it as parent
之一Yo's avatar
之一Yo 已提交
19
        self.widget = QFrame(self, objectName='centerWidget')
之一Yo's avatar
之一Yo 已提交
20 21 22 23
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setGeometry(0, 0, parent.width(), parent.height())

24
        c = 0 if isDarkTheme() else 255
之一Yo's avatar
之一Yo 已提交
25
        self.windowMask.resize(self.size())
之一Yo's avatar
之一Yo 已提交
26
        self.windowMask.setStyleSheet(f'background:rgba({c}, {c}, {c}, 0.6)')
之一Yo's avatar
之一Yo 已提交
27
        self._hBoxLayout.addWidget(self.widget)
之一Yo's avatar
之一Yo 已提交
28 29 30
        self.setShadowEffect()

        self.window().installEventFilter(self)
之一Yo's avatar
之一Yo 已提交
31

之一Yo's avatar
之一Yo 已提交
32
    def setShadowEffect(self, blurRadius=60, offset=(0, 10), color=QColor(0, 0, 0, 100)):
之一Yo's avatar
之一Yo 已提交
33 34
        """ add shadow to dialog """
        shadowEffect = QGraphicsDropShadowEffect(self.widget)
之一Yo's avatar
之一Yo 已提交
35 36 37 38
        shadowEffect.setBlurRadius(blurRadius)
        shadowEffect.setOffset(*offset)
        shadowEffect.setColor(color)
        self.widget.setGraphicsEffect(None)
之一Yo's avatar
之一Yo 已提交
39 40
        self.widget.setGraphicsEffect(shadowEffect)

之一Yo's avatar
之一Yo 已提交
41 42 43 44 45 46
    def setMaskColor(self, color: QColor):
        """ set the color of mask """
        self.windowMask.setStyleSheet(f"""
            background: rgba({color.red()}, {color.blue()}, {color.green()}, {color.alpha()})
        """)

之一Yo's avatar
之一Yo 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
    def showEvent(self, e):
        """ fade in """
        opacityEffect = QGraphicsOpacityEffect(self)
        self.setGraphicsEffect(opacityEffect)
        opacityAni = QPropertyAnimation(opacityEffect, b'opacity', self)
        opacityAni.setStartValue(0)
        opacityAni.setEndValue(1)
        opacityAni.setDuration(200)
        opacityAni.setEasingCurve(QEasingCurve.InSine)
        opacityAni.finished.connect(opacityEffect.deleteLater)
        opacityAni.start()
        super().showEvent(e)

    def closeEvent(self, e):
        """ fade out """
        self.widget.setGraphicsEffect(None)
        opacityEffect = QGraphicsOpacityEffect(self)
        self.setGraphicsEffect(opacityEffect)
        opacityAni = QPropertyAnimation(opacityEffect, b'opacity', self)
        opacityAni.setStartValue(1)
        opacityAni.setEndValue(0)
        opacityAni.setDuration(100)
        opacityAni.setEasingCurve(QEasingCurve.OutCubic)
        opacityAni.finished.connect(self.deleteLater)
        opacityAni.start()
        e.ignore()
之一Yo's avatar
之一Yo 已提交
73 74 75 76 77 78 79 80 81 82 83

    def resizeEvent(self, e):
        self.windowMask.resize(self.size())

    def eventFilter(self, obj, e: QEvent):
        if obj is self.window():
            if e.type() == QEvent.Resize:
                re = QResizeEvent(e)
                self.resize(re.size())

        return super().eventFilter(obj, e)