PyQt5 使用 QFrame 实现页面类抽屉式的进入与退出的动画

PyQt5 使用 QFrame 实现页面类抽屉式的进入与退出的动画

当多个页面切换,但是又不想每个页面里的内容只是简单的出现与消失,则可以使用这个QPropertyAnimation动画

代码结构

本文中全部代码全在test_QFrame_Animation.py这一个文件中编码,步骤中有变动的地方会注释标注,无改动的不会重复显示出来,需要看完整代码的,可直接移步到末尾。

一. 创建测试页面

添加QFrame,用于实现动画效果,并添加两个QPushButton按钮,用于提供触发信号

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File        : test_QFrame_Animation.py
@ Author      : yqbao
@ Version     : V1.0.0
@ Description : QFrame 实现页面类抽屉式的进入与退出的动画
"""
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QFrame, QGraphicsOpacityEffect
from PyQt5.QtCore import QRect, QPropertyAnimation


class Ui_Window(object):
    def setupUi(self, Window):
        Window.setObjectName("Window")
        Window.resize(800, 200)

        # 创建按钮触发进入动画
        self.start_button = QPushButton(Window)
        self.start_button.setText("进入")
        self.start_button.setGeometry(QRect(330, 10, 130, 23))

        # 创建按钮触发退出动画
        self.exit_button = QPushButton(Window)
        self.exit_button.setText("退出")
        self.exit_button.setGeometry(QRect(330, 40, 130, 23))

        # 创建QFrame并设置初始位置在窗口下方位置70
        self.frame = QFrame(Window)
        self.frame.setGeometry(50, 70, 700, 120)  # 初始位置为 x=50,y=70
        self.frame.setStyleSheet("background-color: lightblue;")  # 背景色

测试页面如图:
image

二. 设置QFrame的初始状态

启动图形透明度,并设置QFrame,初始透明度为完全透明

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File        : test_QFrame_Animation.py
@ Author      : yqbao
@ Version     : V1.0.0
@ Description : QFrame 实现页面类抽屉式的进入与退出的动画
"""

class Ui_Window(object):
    ...  # 忽略,无改动


class Window(QWidget, Ui_Window):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        # 设置 QFrame 为透明,然后后续在动画中,边修改透明度边移动
        self.opacity_effect = QGraphicsOpacityEffect()
        self.frame.setGraphicsEffect(self.opacity_effect)
        self.opacity_effect.setOpacity(0)  # 初始透明度为0(完全透明)

此时无法看见QFrame但其实他就在那个位置。
image

三. 为QFrame添加属性动画

添加两个方法,分别实现进入与退出效果,其中动画的主要作用就是修改QFrame的位置与透明度,其中修改位置时,xy坐标遵循的是左上角x=0,y=0,右下角x=高度,y=宽度,所以x越大,位置越靠近右侧,y越大,位置越靠近底部,

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File        : test_QFrame_Animation.py
@ Author      : yqbao
@ Version     : V1.0.0
@ Description : QFrame 实现页面类抽屉式的进入与退出的动画
"""

class Ui_Window(object):
    ...  # 忽略,无改动


class Window(QWidget, Ui_Window):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        ...  # 忽略,无改动

        # 增加 按钮点击信号连接
        self.start_button.clicked.connect(self.start_animation)
        self.exit_button.clicked.connect(self.exit_animation)

    def start_animation(self):
        # 设置QFrame的geometry属性
        self.move_animation = QPropertyAnimation(self.frame, b"geometry")
        self.move_animation.setDuration(200)  # 动画持续时间为200ms
        self.move_animation.setStartValue(QRect(50, 110, 700, 120))  # 动画开始时的位置
        self.move_animation.setEndValue(QRect(50, 70, 700, 120))  # 动画结束时的位置

        # 设置QFrame的透明度属性
        self.opacity_animation = QPropertyAnimation(self.opacity_effect, b"opacity")
        self.opacity_animation.setDuration(200)  # 动画持续时间为200ms
        self.opacity_animation.setStartValue(0)  # 动画开始时的透明度(完全透明)
        self.opacity_animation.setEndValue(1)  # 动画结束时的透明度(完全不透明)

        # 启动动画
        self.move_animation.start()
        self.opacity_animation.start()

    def exit_animation(self):
        # 设置QFrame的geometry属性
        self.move_animation = QPropertyAnimation(self.frame, b"geometry")
        self.move_animation.setDuration(200)  # 动画持续时间为200ms
        self.move_animation.setStartValue(QRect(50, 70, 700, 120))  # 动画开始时的位置
        self.move_animation.setEndValue(QRect(50, 110, 700, 120))  # 动画结束时的位置

        # 设置QFrame的透明度属性
        self.opacity_animation = QPropertyAnimation(self.opacity_effect, b"opacity")
        self.opacity_animation.setDuration(200)  # 动画持续时间为200ms
        self.opacity_animation.setStartValue(1)  # 动画开始时的透明度(完全不透明)
        self.opacity_animation.setEndValue(0)  # 动画结束时的透明度(完全透明)

        # 启动动画
        self.move_animation.start()
        self.opacity_animation.start()

效果为从下往上进入,与从上向下退出:
image

四. 完整代码

随便在QFrame中添加一些小部件,使其一起出现与退出

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File        : test_QFrame_Animation.py
@ Author      : yqbao
@ Version     : V1.0.0
@ Description : QFrame 实现页面类抽屉式的进入与退出的动画
"""
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QFrame, QGraphicsOpacityEffect
from PyQt5.QtCore import QRect, QPropertyAnimation


class Ui_Window(object):
    def setupUi(self, Window):
        Window.setObjectName("Window")
        Window.resize(800, 200)

        # 创建按钮触发进入动画
        self.start_button = QPushButton(Window)
        self.start_button.setText("进入")
        self.start_button.setGeometry(QRect(330, 10, 130, 23))

        # 创建按钮触发退出动画
        self.exit_button = QPushButton(Window)
        self.exit_button.setText("退出")
        self.exit_button.setGeometry(QRect(330, 40, 130, 23))

        # 创建QFrame并设置初始位置在窗口下方位置70
        self.frame = QFrame(Window)
        self.frame.setGeometry(50, 70, 700, 120)  # 初始位置为 x=50,y=70
        self.frame.setStyleSheet("background-color: lightblue;")  # 背景色


class Window(QWidget, Ui_Window):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        # 设置 QFrame 为透明,然后后续在动画边修改透明度,边移动
        self.opacity_effect = QGraphicsOpacityEffect()
        self.frame.setGraphicsEffect(self.opacity_effect)
        self.opacity_effect.setOpacity(0)  # 初始透明度为0(完全透明)

        self.start_button.clicked.connect(self.start_animation)
        self.exit_button.clicked.connect(self.exit_animation)

    def start_animation(self):
        # 设置QFrame的geometry属性
        self.move_animation = QPropertyAnimation(self.frame, b"geometry")
        self.move_animation.setDuration(200)  # 动画持续时间为200ms
        self.move_animation.setStartValue(QRect(50, 110, 700, 120))  # 动画开始时的位置
        self.move_animation.setEndValue(QRect(50, 70, 700, 120))  # 动画结束时的位置

        # 设置QFrame的透明度属性
        self.opacity_animation = QPropertyAnimation(self.opacity_effect, b"opacity")
        self.opacity_animation.setDuration(200)  # 动画持续时间为200ms
        self.opacity_animation.setStartValue(0)  # 动画开始时的透明度(完全透明)
        self.opacity_animation.setEndValue(1)  # 动画结束时的透明度(完全不透明)

        # 启动动画
        self.move_animation.start()
        self.opacity_animation.start()

    def exit_animation(self):
        # 设置QFrame的geometry属性
        self.move_animation = QPropertyAnimation(self.frame, b"geometry")
        self.move_animation.setDuration(200)  # 动画持续时间为200ms
        self.move_animation.setStartValue(QRect(50, 70, 700, 120))  # 动画开始时的位置
        self.move_animation.setEndValue(QRect(50, 110, 700, 120))  # 动画结束时的位置

        # 设置QFrame的透明度属性
        self.opacity_animation = QPropertyAnimation(self.opacity_effect, b"opacity")
        self.opacity_animation.setDuration(200)  # 动画持续时间为200ms
        self.opacity_animation.setStartValue(1)  # 动画开始时的透明度(完全不透明)
        self.opacity_animation.setEndValue(0)  # 动画结束时的透明度(完全透明)

        # 启动动画
        self.move_animation.start()
        self.opacity_animation.start()


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec_())

本文章的原文地址
GitHub主页

posted @ 2024-09-27 23:00  星尘的博客  阅读(1)  评论(0编辑  收藏  举报