PyQt5实现类似安卓Toast

用pyqt写了一个类似与android的Toast提示框,图片需要自己换路径

# -*- coding: utf-8 -*-


from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.Qt import Qt


class Toast(QWidget):

    style = '''
#lb_message{
    color:#f7faff;
    font-family:Microsoft YaHei;
}
    '''

    def __init__(self, message='', state=0, msc=3000, parent=None):
        super(Toast, self).__init__(parent)

        # 除了成功之外其他消息图标一律使用错误图标(有局限性:成功的具体信息有很多种,但这里没办法区分,待改)
        if state != 0:
            self.iconPath = ':/icon/error.png'
        else:
            self.iconPath = ':/icon/success.png'
        self.message = message  # 需要显示的消息


        self.msc = msc  # 窗口显示时长
        self.timer = QTimer()
        # 由于不知道动画结束的事件,所以借助QTimer来关闭窗口,动画结束就关闭窗口,所以这里的事件要和动画时间一样
        self.timer.singleShot(self.msc, self.close)  # singleShot表示timer只会启动一次

        self.setUpUi()
        self.createAnimation()


    def setUpUi(self):
        self.setWindowFlags(Qt.FramelessWindowHint|Qt.WindowStaysOnTopHint | Qt.SubWindow)  # 这样就不会在任务栏上显示
        # self.setWindowOpacity(0.9)  # 设置窗口透明度
        self.setAttribute(Qt.WA_TranslucentBackground)  # 设置窗口透明
        self.setObjectName('Toast')
        self.setMinimumSize(QSize(220, 100))
        self.setMaximumSize(QSize(220, 180))
        self.horizontalLayout = QHBoxLayout(self)
        self.horizontalLayout.setContentsMargins(20, -1, 20, -1)
        self.horizontalLayout.setSpacing(15)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.lb_icon = QLabel()
        self.lb_icon.setText("")
        self.lb_icon.setObjectName("lb_icon")
        self.lb_icon.setPixmap(QPixmap(self.iconPath))
        self.horizontalLayout.addWidget(self.lb_icon)
        self.lb_message = QLabel(self)
        '''实现QLabel自动换行'''
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.lb_message.sizePolicy().hasHeightForWidth())
        self.lb_message.setSizePolicy(sizePolicy)
        self.lb_message.setWordWrap(True)
        self.lb_message.setText(self.message)
        self.lb_message.setTextFormat(Qt.AutoText)
        self.lb_message.setScaledContents(True)
        self.lb_message.setObjectName("lb_message")
        self.lb_message.setAlignment(Qt.AlignCenter)
        self.horizontalLayout.addWidget(self.lb_message)

        self.setStyleSheet(self.style)

        self.center()


    def paintEvent(self, a0: QPaintEvent):
        qp = QPainter()
        qp.begin(self)  # 不能掉,不然没效果
        qp.setRenderHints(QPainter.Antialiasing, True)  # 抗锯齿
        qp.setBrush(QBrush(Qt.black))
        qp.setPen(Qt.transparent)
        rect = self.rect()
        rect.setWidth(rect.width() - 1)
        rect.setHeight(rect.height() - 1)
        qp.drawRoundedRect(rect, 15, 15)
        qp.end()

    def createAnimation(self):
        # 1.定义一个动画
        self.animation = QPropertyAnimation(self, b'windowOpacity')
        self.animation.setTargetObject(self)
        # self.animation.setPropertyName(b"windowOpacity")
        # 2.设置属性值
        self.animation.setStartValue(0)
        self.animation.setKeyValueAt(0.2, 0.7)  # 设置插值0.3 表示单本次动画时间的0.3处的时间点
        self.animation.setKeyValueAt(0.8, 0.7)  # 设置插值0.8 表示单本次动画时间的0.3处的时间点
        self.animation.setEndValue(0)
        # 3.设置时长
        self.animation.setDuration(self.msc)
        # 4.启动动画
        self.animation.start()

    def center(self):
        if self.parent() is not None:
            xPos = int((self.parent().width() - self.width())/2)
            yPos = int((self.parent().height() - self.height())/2+40)
            self.move(xPos, yPos)
        else:
            # 屏幕居中
            screen = QDesktopWidget().screenGeometry()
            size = self.geometry()
            self.move(int((screen.width() - size.width()) / 2),
                      int((screen.height() - size.height()) / 2)+40)

class Window(QWidget):

    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        self.resize(400, 400)
        layout = QVBoxLayout(self)
        layout.addWidget(QPushButton('显示Toast', self, clicked=self.showToast))

    def showToast(self):
        # Toast(parent=self).show()  # 用这个动画失效
        Toast().show()

if __name__ == '__main__':
    import sys
    from PyQt5.QtWidgets import QApplication
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec_())

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值