如何修改PyQt5窗口的不透明度并实现不透明度动画效果
问题原因
- 顶层QWidget(作为主窗口的根控件)不适合用
QGraphicsOpacityEffect实现不透明度动画:Qt的图形效果依赖父控件的合成渲染逻辑,而顶层窗口由系统窗口管理器直接管理,两者的渲染逻辑冲突,就会出现界面不自动更新、背景变黑、控件点击反馈异常的问题。 - 冗余逻辑过多:你额外添加的
QTimer完全不需要,QPropertyAnimation本身会自动更新绑定属性并触发界面重绘,反复调用update()反而会抢占UI线程资源,加剧卡顿;另外给QPushButton调用show()也属于冗余操作,父控件显示时可见的子控件会自动显示。 - 命名不规范:你将
QApplication实例命名为window,窗口实例命名为app,属于明显的命名颠倒,虽然不影响运行,但不符合通用编码习惯。
解决方案
直接对顶层窗口自带的windowOpacity属性做动画即可,这是Qt专门提供给顶层窗口修改不透明度的属性,没有渲染兼容问题,代码也更简洁。
修正后的代码
from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * import sys class Test(QWidget): def __init__(self): super().__init__() self.setStyleSheet("background: green") self.setGeometry(100, 100, 400, 400) self.b = QPushButton("Reduce", self, clicked=self.reduce) self.b.setStyleSheet("color: yellow") self.show() def reduce(self): # 直接对windowOpacity属性做动画,不需要图形效果和定时器 self.anim = QPropertyAnimation(self, b"windowOpacity") self.anim.setDuration(500) self.anim.setStartValue(1) self.anim.setEndValue(0) self.anim.start() if __name__ == "__main__": # 修正命名规范 app = QApplication(sys.argv) window = Test() app.exec_()
补充说明
如果你后续需要给顶层窗口的整体内容加其他图形效果(比如模糊、变色等),可以在顶层窗口里放一个铺满整个窗口的子QWidget,所有控件都放在这个子QWidget上,再给这个子QWidget加图形效果,就能避免顶层窗口的渲染兼容问题。
内容的提问来源于stack exchange,提问作者blunty6363
相关产品推荐
相关产品推荐

