首页 > 其他分享 >PyQt5 使用 QStackedWidget 实现轮播展示动画,但是却疯狂闪烁的解决办法

PyQt5 使用 QStackedWidget 实现轮播展示动画,但是却疯狂闪烁的解决办法

时间:2024-09-20 13:35:57浏览次数:10  
标签:opacity 轮播 self effect PyQt5 next button page QStackedWidget

PyQt5 使用 QStackedWidget 实现轮播展示动画,但是却疯狂闪烁的解决办法

上篇说到,上篇见这里 我们可能会遇到,当把鼠标移动到 "下一页" 和 "上一页" 按钮,又或者是 Qlabel标签页时,就会疯狂闪烁,于是在这里换另一种方案,解决这个问题

代码结构

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

一. 修改代码

1. 修改DemoApp__init__,启动透明度效果

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File        : test_QStackedWidget_Animation.py
@ Author      : yqbao
@ Version     : V1.0.0
@ Description : 图片轮播动画
"""
class DemoApp(QWidget):
    def __init__(self):
        super().__init__()
        ... # 忽略

        # 隐藏按钮和标签初始状态
        # self.button_next.hide()  # 注释这3行
        # self.button_prev.hide()
        # self.hide_current_page()

        # 启用透明度效果
        self.opacity_effect_prev = QGraphicsOpacityEffect(self.button_prev)
        self.button_prev.setGraphicsEffect(self.opacity_effect_prev)
        self.opacity_effect_prev.setOpacity(0)

        self.opacity_effect_next = QGraphicsOpacityEffect(self.button_next)
        self.button_next.setGraphicsEffect(self.opacity_effect_next)
        self.opacity_effect_next.setOpacity(0)

        # 设置透明背景
        self.button_prev.setAttribute(Qt.WA_TranslucentBackground)
        self.button_next.setAttribute(Qt.WA_TranslucentBackground)
        self.hide_current_page()

2. 修改DemoApphide_current_page方法

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File        : test_QStackedWidget_Animation.py
@ Author      : yqbao
@ Version     : V1.0.0
@ Description : 图片轮播动画
"""
def hide_current_page(self):
    """隐藏标签页"""
    # for label in self.page_labels:
    #     label.hide()
    for label in self.page_labels:
        self.opacity_effect_next = QGraphicsOpacityEffect(label)
        label.setGraphicsEffect(self.opacity_effect_next)
        self.opacity_effect_next.setOpacity(0)

3. 在DemoApp中增加两个新方法,使用属性动画,修改透明度

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File        : test_QStackedWidget_Animation.py
@ Author      : yqbao
@ Version     : V1.0.0
@ Description : 图片轮播动画
"""
@staticmethod
def fade_in(widget):
    opacity_effect = widget.graphicsEffect()
    animation = QPropertyAnimation(opacity_effect, b"opacity")
    animation.setDuration(200)
    animation.setStartValue(1)
    animation.setEndValue(0)
    animation.start()

@staticmethod
def fade_out(widget):
    opacity_effect = widget.graphicsEffect()
    animation = QPropertyAnimation(opacity_effect, b"opacity")
    animation.setDuration(200)
    animation.setStartValue(0)
    animation.setEndValue(1)
    animation.start()

4. 修改DemoAppeventFilter方法

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File        : test_QStackedWidget_Animation.py
@ Author      : yqbao
@ Version     : V1.0.0
@ Description : 图片轮播动画
"""
def eventFilter(self, obj, event):
    """事件过滤,鼠标移入与移出"""
    if event.type() == QEvent.Enter and obj is self:
        self.fade_in(self.button_next)
        self.fade_in(self.button_prev)
        for label in self.page_labels:
            self.fade_in(label)
    elif event.type() == QEvent.Leave and obj is self:
        self.fade_out(self.button_next)
        self.fade_out(self.button_prev)
        for label in self.page_labels:
            self.fade_out(label)
    return super().eventFilter(obj, event)

image

二. DemoApp完整代码

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
@ File        : test_QStackedWidget_Animation.py
@ Author      : yqbao
@ Version     : V1.0.0
@ Description : 图片轮播动画
"""
from PyQt5.QtWidgets import QApplication, QWidget, QStackedWidget, QVBoxLayout, QPushButton, QLabel, \
    QGraphicsOpacityEffect
from PyQt5.QtCore import QPropertyAnimation, QEasingCurve, QRect, QEvent, Qt, QTimer


class DemoApp(QWidget, Ui_DemoApp):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        # 连接按钮事件
        self.button_next.clicked.connect(self.next_page)
        self.button_prev.clicked.connect(self.prev_page)

        # 启用透明度效果
        self.opacity_effect_prev = QGraphicsOpacityEffect(self.button_prev)
        self.button_prev.setGraphicsEffect(self.opacity_effect_prev)
        self.opacity_effect_prev.setOpacity(0)

        self.opacity_effect_next = QGraphicsOpacityEffect(self.button_next)
        self.button_next.setGraphicsEffect(self.opacity_effect_next)
        self.opacity_effect_next.setOpacity(0)

        # 设置透明背景
        self.button_prev.setAttribute(Qt.WA_TranslucentBackground)
        self.button_next.setAttribute(Qt.WA_TranslucentBackground)
        self.hide_current_page()

        # 高亮当前页码
        self.highlight_current_page()

        # 定时器设置
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.auto_next_page)  # 自动轮播
        self.timer.start(3000)  # 每3秒切换一次

        # 安装事件过滤器到窗口
        self.installEventFilter(self)

    def auto_next_page(self):
        """自动切换到下一页"""
        self.next_page()

    def reset_timer(self):
        """重置定时器,以保持自动轮播"""
        self.timer.start(3000)


    def hide_current_page(self):
        """隐藏标签页"""
        for label in self.page_labels:
            self.opacity_effect_next = QGraphicsOpacityEffect(label)
            label.setGraphicsEffect(self.opacity_effect_next)
            self.opacity_effect_next.setOpacity(0)

    def set_geometry_current_page(self):
        """设置标签页位置"""
        for i, label in enumerate(self.page_labels):
            label.setGeometry(self.width() // 2 + i * 15 - 30, self.height() - 45, 60, 30)

    @staticmethod
    def fade_in(widget):
        opacity_effect = widget.graphicsEffect()
        animation = QPropertyAnimation(opacity_effect, b"opacity")
        animation.setDuration(200)
        animation.setStartValue(1)
        animation.setEndValue(0)
        animation.start()

    @staticmethod
    def fade_out(widget):
        opacity_effect = widget.graphicsEffect()
        animation = QPropertyAnimation(opacity_effect, b"opacity")
        animation.setDuration(200)
        animation.setStartValue(0)
        animation.setEndValue(1)
        animation.start()

    def eventFilter(self, obj, event):
        """事件过滤,鼠标移入与移出"""
        if event.type() == QEvent.Enter and obj is self:
            self.fade_in(self.button_next)
            self.fade_in(self.button_prev)
            for label in self.page_labels:
                self.fade_in(label)
        elif event.type() == QEvent.Leave and obj is self:
            self.fade_out(self.button_next)
            self.fade_out(self.button_prev)
            for label in self.page_labels:
                self.fade_out(label)
        return super().eventFilter(obj, event)

    def highlight_current_page(self, index=0):
        """更新标签样式"""
        for i, label in enumerate(self.page_labels):
            if i == index:
                label.setStyleSheet("color: black; font-weight: bold;")  # 高亮当前页码
            else:
                label.setStyleSheet("color: gray;")  # 暗淡其他页码

    def next_page(self):
        """下一页"""
        current_index = self.stacked_widget.currentIndex()
        next_index = (current_index + 1) % self.stacked_widget.count()
        self.stacked_widget.set_current_index_with_animation(next_index, direction='left')
        self.highlight_current_page(next_index)
        self.reset_timer()

    def prev_page(self):
        """上一页"""
        current_index = self.stacked_widget.currentIndex()
        prev_index = (current_index - 1) % self.stacked_widget.count()
        self.stacked_widget.set_current_index_with_animation(prev_index, direction='right')
        self.highlight_current_page(prev_index)
        self.reset_timer()

    def resizeEvent(self, event):
        """更新按钮位置"""
        super().resizeEvent(event)
        self.button_next.setGeometry(self.width() - 80, self.height() // 2 - 15, 60, 30)
        self.button_prev.setGeometry(20, self.height() // 2 - 15, 60, 30)
        self.set_geometry_current_page()

本文章的原文地址
GitHub主页

标签:opacity,轮播,self,effect,PyQt5,next,button,page,QStackedWidget
From: https://www.cnblogs.com/yqbaowo/p/18422153

相关文章

  • Android静态轮播图
    在Android中实现静态轮播图,通常指的是在一个固定的布局中显示一系列图片,并且这些图片会按照一定的时间间隔自动切换。这种效果可以通过多种方式实现,比如使用ViewPager结合PagerAdapter,或者使用ViewFlipper等组件。下面我将给出一个基于ViewPager的简单示例。使用ViewPager实现轮播......
  • 【w0网页制作】Html+Css网页制作影视主题之庆余年Ⅱ含轮播表单(5页面附源码)
    庆余年2HTML+CSS网页开发目录......
  • PyQt5 使用 QStackedWidget 实现轮播展示动画(自动与手动)
    PyQt5使用QStackedWidget实现轮播展示动画(自动与手动)在PyQt5中,如果需要用QStackedWidget展示图片比较生硬,参考网络上的一些内容,发现用QPropertyAnimation属性动画可实现想要的效果,于是记录在这里代码结构本文中全部代码全在test_QStackedWidget_Animation.py这一个文件中......
  • PyQt5 使用 QFrame 绘制聊天(三角)气泡,并显示文字
    PyQt5使用QFrame绘制聊天(三角)气泡,并显示文字在PyQt5中,当需要想得到一个自定义的聊天气泡时,可以使用QPainter进行自定义绘制代码如下使用QPainter进行自定义绘制#!/usr/bin/envpython3#-*-coding:UTF-8-*-"""@File:test_QFrame.py@Author:......
  • PbootCMS幻灯片轮播图怎么调用
    在PBootCMS中,使用幻灯片轮播图标签可以方便地在全站任意位置调用指定分组的幻灯片图片。以下是如何使用该标签的具体步骤和示例代码。1.幻灯片轮播图列表基本用法html {pboot:slidegid=*num=*}<imgsrc="[slide:src]">{/pboot:slide}2.控制参数gid=*:分组......
  • PyQt5--打造精美、功能强大的桌面应用程序
    ui文件转换为python文件方法一:直接使用命令行转换,demo.ui为保存的ui名,demo.py为ui转换为python的文件。1python-mPyQt5.uic.pyuicdemo.ui-odemo.py QLabel案例:使用信号以下是QLabel控件的常用信号:linkActivated:当控件中包含超链接时,用户单击链接时触发此信号。......
  • 【看来我要63岁才能退休了】超简单!低耦合!一步在自己PyQt5、PySide6界面中加入文件资源
    【......
  • iOS开发----轮播图实现
    在iOS开发中,实现图片轮播的方法有很多,在这里介绍三种方法。轮播图片资源准备——SDWebImage这里我们通过第三方库SDWebImage来加载网络图片首先通过CocoaPods下载:接着,从网站上找想要轮播图片的地址,复制下来,y一般是下图这样,在代码中,使用UIImageView的扩展方法sd_setImage......
  • Pyqt5 实现计算器
    计算器是练习pyqt5的好项目界面设计简单 代码如下:importsysfromPyQt5.QtWidgetsimport*fromPyQt5.QtCoreimportQtclassWindow(QWidget):def__init__(self):super().__init__()self.display=Noneself.buttons=None......
  • Javascript应用(轮播图进阶)
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</title>......