# coding:utf-8 import textwrap from PyQt5.QtCore import Qt, pyqtSignal, QPropertyAnimation, QEasingCurve, QAbstractAnimation from PyQt5.QtWidgets import (QDialog, QGraphicsDropShadowEffect, QGraphicsOpacityEffect, QLabel, QPushButton, QWidget) class MaskDialog(QDialog): yesSignal = pyqtSignal() cancelSignal = pyqtSignal() def __init__(self, title: str, content: str, parent): super().__init__(parent=parent) self.content = content self.windowMask = QWidget(self) self.widget = QWidget(self) self.titleLabel = QLabel(title, self.widget) self.contentLabel = QLabel(content, self.widget) self.yesButton = QPushButton('确定', self.widget) self.cancelButton = QPushButton('取消', self.widget) self.__initWidget() def __initWidget(self): """ 初始化小部件 """ self.__setShadowEffect() self.widget.setWindowOpacity(0.1) self.setWindowFlags(Qt.FramelessWindowHint) self.setAttribute(Qt.WA_TranslucentBackground) self.setGeometry(0, 0, self.parent().width(), self.parent().height()) self.windowMask.resize(self.size()) self.widget.setMaximumWidth(675) self.titleLabel.move(30, 30) self.contentLabel.move(30, 70) self.contentLabel.setText('\n'.join(textwrap.wrap(self.content, 36))) # 设置层叠样式 self.__setQss() # 调节内部对话框大小并居中 self.__initLayout() # 信号连接到槽 self.yesButton.clicked.connect(self.__onYesButtonClicked) self.cancelButton.clicked.connect(self.__onCancelButtonClicked) def __setShadowEffect(self): """ 添加阴影 """ shadowEffect = QGraphicsDropShadowEffect(self.widget) shadowEffect.setBlurRadius(50) shadowEffect.setOffset(0, 5) self.widget.setGraphicsEffect(shadowEffect) def showEvent(self, e): """ 淡入 """ 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): """ 淡出 """ 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() def __initLayout(self): """ 初始化布局 """ self.contentLabel.adjustSize() self.widget.setFixedSize(60+self.contentLabel.width(), self.contentLabel.y() + self.contentLabel.height()+115) self.widget.move(self.width()//2 - self.widget.width()//2, self.height()//2 - self.widget.height()//2) self.yesButton.resize((self.widget.width() - 68) // 2, 40) self.cancelButton.resize(self.yesButton.width(), 40) self.yesButton.move(30, self.widget.height()-70) self.cancelButton.move( self.widget.width()-30-self.cancelButton.width(), self.widget.height()-70) def __onCancelButtonClicked(self): self.cancelSignal.emit() self.close() def __onYesButtonClicked(self): self.yesSignal.emit() self.close() def __setQss(self): """ 设置层叠样式 """ self.windowMask.setObjectName('windowMask') self.titleLabel.setObjectName('titleLabel') self.contentLabel.setObjectName('contentLabel') with open('resource/mask_dialog.qss', encoding='utf-8') as f: self.setStyleSheet(f.read())