最近写一个程序用到 PyQt5,其中需要让一个 label 标签实现淡入效果,即透明度的渐变效果。上网搜了很久,都只有窗口的淡入淡出,而没有控件的淡入淡出的实现方法。自己研究后写了一个方法实现这个效果,写在这里做个记录。
窗体关闭淡出
前面先扯一下窗口的淡入淡出。窗口淡出可以直接使用动画 QPropertyAnimation 。
直接放代码:
import sys
from PyQt5.QtWidgets import QApplication, QLabel
from PyQt5.QtCore import QPropertyAnimation, QTimer
class QmyWindow(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.anim = None
def 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
。
效果:
控件淡入淡出
试验发现,窗体淡出方法不适用于控件,无效果。我了解到可能是因为 windowOpacity
只对顶层窗口起作用。
于是我尝试通过循环,不断重新设置控件的透明度,达到渐变效果。但我发现行不通,没有任何效果,而且会造成堵塞。
最后我搞了个定时器 QTimer,终于解决了这个问题:
import sys
from PyQt5.QtWidgets import QApplication, QLabel
from PyQt5.QtCore import QPropertyAnimation, QTimer
from PyQt5.QtGui import QPalette
class 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)
self.label.setGraphicsEffect(self.opacity)
self.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 += 1
if self.opacity.i >= 100:
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_())
控件淡出的代码也是类似。
效果: