最近写一个程序用到 PyQt5,其中需要让一个 label 标签实现淡入效果,即透明度的渐变效果。上网搜了很久,都只有窗口的淡入淡出,而没有控件的淡入淡出的实现方法。自己研究后写了一个方法实现这个效果,写在这里做个记录。
本篇文章内容
1. 控件淡入淡出效果2. 窗体关闭淡出1. 控件淡入淡出效果
对于控件淡入淡出,我原本计划使用透明度属性动画 QPropertyAnimation。就像这样:
self.anim = QPropertyAnimation(self.label, b"windowOpacity")
试验发现,透明度渐变动画不适用于控件,无效果。却适用于窗体的淡出。我了解到可能是因为windowOpacity
只对顶层窗口起作用。
于是我尝试通过循环,不断重新设置控件的透明度,达到渐变效果。但我发现行不通,没有任何效果,而且会造成堵塞。
最后我搞了个定时器 QTimer,终于解决了这个问题:
import sysfrom PyQt5.QtWidgets import QApplication, QLabelfrom PyQt5.QtCore import QPropertyAnimation, QTimerfrom PyQt5.QtGui import QPaletteclass QmyWindow(QWidget): def __init__(self, parent=None):super().__init__(parent)self.label = QLabel(self)self.label.setText('控件淡入')self.label.setAutoFillBackground(True)# 设置标签背景色palette = QPalette()palette.setColor(QPalette.Window, QColor(141, 91, 153))self.label.setPalette(palette)# 设置透明度self.opacity = QGraphicsOpacityEffect() # 透明度对象self.opacity.setOpacity(0) # 初始化设置透明度为0,即完全透明self.label.setGraphicsEffect(self.opacity) # 把标签的透明度设置为为self.opacityself.draw() # 淡入效果开始def draw(self):self.opacity.i = 1 # 用于记录透明度变化与循环次数def timeout(): # 超时函数:改变透明度self.opacity.setOpacity(self.opacity.i/100)self.label.setGraphicsEffect(self.opacity) # 改变标签透明度self.opacity.i += 1if self.opacity.i >= 100: # 此时透明度为1,即不透明,控件已经完全显示出来了self.timer.stop() # 计时器停止self.timer.deleteLater()self.timer = QTimer() # 计时器self.timer.setInterval(10) # 设置间隔时间,毫秒为单位self.timer.timeout.connect(timeout) # 超时槽函数,每到达间隔时间,调用该函数self.timer.start() # 计时器开始if __name__ == '__main__': # 用于当前窗体测试app = QApplication(sys.argv) # 创建GUI应用程序form = QmyWindow() # 创建窗体form.show() # 显示窗体sys.exit(app.exec_())
self.opacity = QGraphicsOpacityEffect()
实例化一个透明度对象self.opacity.setOpacity(0)
设置透明度为0,即完全透明。参数为0~1.0之间的小数。self.label.setGraphicsEffect(self.opacity)
将控件的透明度设为 self.opacity
这里实现渐变效果的思路就是,设置一个以 0.01 秒为间隔的定时器,每过 0.01 秒,就把控件的透明度设为已经经过的秒数的数值(即增加 0.01),这样可以实现透明度的不断增大。
因为 QTimer 定时器是多线程,因此不会造成阻塞。
控件淡出的代码也是类似。
效果:
2. 窗体关闭淡出
后面再顺便说一下窗口的淡入淡出。窗口淡出可以直接使用动画 QPropertyAnimation 。
直接放代码:
import sysfrom PyQt5.QtWidgets import QApplication, QLabelfrom PyQt5.QtCore import QPropertyAnimation, QTimerclass QmyWindow(QWidget): def __init__(self, parent=None):super().__init__(parent)self.anim = Nonedef closeEvent(self, event):if self.anim == None:self.anim = QPropertyAnimation(self, b"windowOpacity") # 设置动画对象self.anim.setDuration(1000) # 设置动画时长self.anim.setStartValue(1) # 设置初始属性,1.0为不透明self.anim.setEndValue(0) # 设置结束属性,0为完全透明self.anim.finished.connect(self.close) # 动画结束时,关闭窗口self.anim.start() # 开始动画event.ignore() # 忽略事件if __name__ == '__main__': # 用于当前窗体测试app = QApplication(sys.argv) # 创建GUI应用程序form=QmyWindow() # 创建窗体form.show() # 显示窗体sys.exit(app.exec_())
QPropertyAnimation(self
,b"windowOpacity"
)
创建一个属性动画,可以改变对象的属性,其中:
self:要设置动画的控件对象
b’windowOpacity’:动画属性值(还可以是 geometry,pos,size 等),需为QByteArray类型,或在字符串前加b
。
效果:
写在最后——
希望本篇文章能帮助到你,如果你有什么疑问或者更好的方法,欢迎在评论区提出。