思路
网上没有合适的弹框公开,只能自己写个,虽然比较简单,但是从零开始思考怎么实现还是需要时间的。
窗口的实现
使用
QDialog
设计一个窗口。
注意:这里也可以用
QWidget
,但是你得保证父控件不是QWidget,否则设置的动画会不显示
class MessageBox(QDialog):
def __init__(self, *args, **kwargs):
super(MessageBox, self).__init__(*args, **kwargs)
self.resize(300, 80)
self.setMinimumSize(300, 80)
# Qt.Window 声明这是一个窗口,如果没有Qt会显示不出来
# Qt.WindowType.FramelessWindowHint 去掉系统自带的边框
# Qt.WindowType.WindowStaysOnTopHint 将窗口置于最上层
self.setWindowFlags(Qt.Window | Qt.WindowType.FramelessWindowHint | Qt.WindowType.WindowStaysOnTopHint)
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) # 将界面属性设置为半透明
self.animation = None
# 如果有父控件,弹框显示到父控件中间
if self.parent():
self.move(self.parent().frameGeometry().center().x() - self.frameGeometry().width() // 2,
self.parent().frameGeometry().center().y() - self.parent().height() // 2 + 100)
半透明效果
Qt自带的设置透明度无法生效,故使用qss实现
rgba()
可以设置单个控件的透明度,设置
QFrame
的透明度,
QFrame
上的控件背景为空,或者
rgba
的最后一个值为0,否则会出现子控件不透明的情况
self.setStyleSheet("*{\n"
" font: 12pt \"黑体\";\n"
"}\n"
"#frame{\n"
" background-color: rgb(0, 0, 0, 0.6);\n"
" border-radius: 20px;\n"
"}\n"
"#label{\n"
" background-color: none;\n"
" border: none;\n"
"}\n"
"#pushButton{\n"
" background-color: none;\n"
" border: none;\n"
" color: rgb(255, 255, 255, 0.8);\n"
" text-align: center;\n"
"}")
控件选择
使用
QVBoxLayout
自适应窗口大小,
QLabel
显示gif图片等,
QPushButton
显示图标与文字
self.verticalLayout = QVBoxLayout(self)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.frame = QFrame(self)
self.frame.setFrameShape(QFrame.StyledPanel)
self.frame.setFrameShadow(QFrame.Raised)
self.frame.setObjectName("frame")
self.verticalLayout_2 = QVBoxLayout(self.frame)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QLabel(self.frame)
self.label.setMinimumSize(QSize(50, 50))
self.label.setMaximumSize(QSize(50, 50))
self.label.setObjectName("label")
self.pushButton = QPushButton(self.frame)
self.pushButton.setMinimumSize(QSize(200, 35))
self.pushButton.setMaximumSize(QSize(10000, 30))
self.pushButton.setObjectName("pushButton")
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.verticalLayout.addWidget(self.frame)
def addMsgIconAndText(self, icon: QIcon() = None, text: str = None):
"""
添加图标和文本
:param icon:
:param text:
:return:
"""
if icon:
self.pushButton.setIcon(icon)
self.pushButton.setIconSize(QSize(50, 50))
if text:
self.pushButton.setText(text)
self.pushButton.adjustSize()
self.horizontalLayout.addWidget(self.pushButton)
def addMsgGif(self, gif_path):
"""
添加gif文件
:param gif_path:
:return:
"""
movie = QMovie(gif_path)
movie.setScaledSize(QSize(50, 50))
self.label.setMovie(movie)
movie.start()
movie.setSpeed(100)
self.horizontalLayout.addWidget(self.label)
自动关闭弹框
使用
QTimer
设置一个定时器,弹框自动关闭
self.timer = QTimer()
self.timer.timeout.connect(self.close)
def setTimerMsec(self, msec: int):
self.timer.start(msec * 1000)
边框阴影
def shadowEffect(obj):
"""
边框阴影
:param obj:
:return:
"""
shadow = QGraphicsDropShadowEffect()
shadow.setBlurRadius(10)
shadow.setColor(QColor(64, 64, 64))
shadow.setOffset(0, 0)
obj.setGraphicsEffect(shadow)
关闭动画
def closeEvent(self, event):
"""
关闭动画
:param event:
:return:
"""
if self.animation is None:
self.animation = QPropertyAnimation(self, b'windowOpacity')
self.animation.setDuration(1000)
self.animation.setStartValue(1)
self.animation.setEndValue(0)
self.animation.finished.connect(self.close)
self.animation.start()
event.ignore()
完整代码
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import QColor, QIcon, QMovie, QMoveEvent
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QFrame, QHBoxLayout, QLabel, QPushButton, QGraphicsDropShadowEffect, \
QApplication
def shadowEffect(obj):
"""
边框阴影
:param obj:
:return:
"""
shadow = QGraphicsDropShadowEffect()
shadow.setBlurRadius(10)
shadow.setColor(QColor(64, 64, 64))
shadow.setOffset(0, 0)
obj.setGraphicsEffect(shadow)
class MessageBox(QDialog):
def __init__(self, *args, **kwargs):
super(MessageBox, self).__init__(*args, **kwargs)
self.resize(300, 80)
self.setMinimumSize(300, 80)
# Qt.Window 声明这是一个窗口,如果没有Qt会显示不出来
# Qt.WindowType.FramelessWindowHint 去掉系统自带的边框
# Qt.WindowType.WindowStaysOnTopHint 将窗口置于最上层
self.setWindowFlags(Qt.Window | Qt.WindowType.FramelessWindowHint | Qt.WindowType.WindowStaysOnTopHint)
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) # 将界面属性设置为半透明
self.setContentsMargins(5, 5, 5, 5)
self.animation = None
# 如果有父控件,弹框显示到父控件中间
if self.parent():
self.move(self.parent().frameGeometry().center().x() - self.frameGeometry().width() // 2,
self.parent().frameGeometry().center().y() - self.parent().height() // 2 + 100)
self.setStyleSheet("*{\n"
" font: 12pt \"黑体\";\n"
"}\n"
"#frame{\n"
" background-color: rgb(0, 0, 0, 0.6);\n"
" border-radius: 35px;\n"
"}\n"
"#label{\n"
" background-color: none;\n"
" border: none;\n"
"}\n"
"#pushButton{\n"
" background-color: none;\n"
" border: none;\n"
" color: rgb(255, 255, 255, 0.8);\n"
" text-align: center;\n"
"}")
self.timer = QTimer()
self.timer.timeout.connect(self.close)
self.verticalLayout = QVBoxLayout(self)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.frame = QFrame(self)
self.frame.setFrameShape(QFrame.StyledPanel)
self.frame.setFrameShadow(QFrame.Raised)
self.frame.setObjectName("frame")
self.verticalLayout_2 = QVBoxLayout(self.frame)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QLabel(self.frame)
self.label.setMinimumSize(QSize(50, 50))
self.label.setMaximumSize(QSize(50, 50))
self.label.setObjectName("label")
self.pushButton = QPushButton(self.frame)
self.pushButton.setMinimumSize(QSize(200, 35))
self.pushButton.setMaximumSize(QSize(10000, 30))
self.pushButton.setObjectName("pushButton")
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.verticalLayout.addWidget(self.frame)
shadowEffect(self.frame)
self.show()
def closeEvent(self, event):
"""
关闭动画
:param event:
:return:
"""
if self.animation is None:
self.animation = QPropertyAnimation(self, b'windowOpacity')
self.animation.setDuration(1000)
self.animation.setStartValue(1)
self.animation.setEndValue(0)
self.animation.finished.connect(self.close)
self.animation.start()
event.ignore()
def addMsgIconAndText(self, icon: QIcon() = None, text: str = None):
"""
添加图标和文本
:param icon:
:param text:
:return:
"""
if icon:
self.pushButton.setIcon(icon)
self.pushButton.setIconSize(QSize(50, 50))
if text:
self.pushButton.setText(text)
self.pushButton.adjustSize()
self.horizontalLayout.addWidget(self.pushButton)
def addMsgGif(self, gif_path):
"""
添加gif文件
:param gif_path:
:return:
"""
movie = QMovie(gif_path)
movie.setScaledSize(QSize(50, 50))
self.label.setMovie(movie)
movie.start()
movie.setSpeed(100)
self.horizontalLayout.addWidget(self.label)
def setTimerMsec(self, msec: int):
"""
设置自动关闭时间
:param msec:
:return:
"""
self.timer.start(msec * 1000)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MessageBox()
win.addMsgIconAndText(text='测试')
win.setTimerMsec(2)
win.show()
sys.exit(app.exec_())
版权声明:本文为weixin_54217201原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。