暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PyQt5 中实现控件淡入淡出效果

zayki 2023-12-24
830

最近写一个程序用到 PyQt5,其中需要让一个 label 标签实现淡入效果,即透明度的渐变效果。上网搜了很久,都只有窗口的淡入淡出,而没有控件的淡入淡出的实现方法。自己研究后写了一个方法实现这个效果,写在这里做个记录。

本篇文章内容

  1. 控件淡入淡出效果
  2. 窗体关闭淡出
  3. 控件淡入淡出效果
    对于控件淡入淡出,我原本计划使用透明度属性动画 QPropertyAnimation。就像这样:

self.anim = QPropertyAnimation(self.label, b"windowOpacity")

试验发现,透明度渐变动画不适用于控件,无效果。却适用于窗体的淡出。我了解到可能是因为 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) # 初始化设置透明度为0,即完全透明
	self.label.setGraphicsEffect(self.opacity) # 把标签的透明度设置为为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: # 此时透明度为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 定时器是多线程,因此不会造成阻塞。

控件淡出的代码也是类似。

  1. 窗体关闭淡出
    后面再顺便说一下窗口的淡入淡出。窗口淡出可以直接使用动画 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。


版权声明:本文为CSDN博主「python xxxyyyxxxyyy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_52132159/article/details/122549237

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论