屏侧“小精灵”是这样制作完成的!

效果展示:

请添加图片描述

导语:

相信大家一定用过QQ宠物或360的智能小球吧,你们一定好奇它这神奇的效果是如何完成的?
今天就让我们用 PySide6 / PyQt 复刻它!

首先分析动画:

界面构成

如上图:这个界面大体是如此构成的。

这个动画分两部分:

  • 内容区向上收缩
  • 功能菜单向左收缩
  • 图片纠正至屏侧

小技巧:
普通动画飞出需要依靠窗口的遮挡或超出显示区域
如何让控件飞出动画不依赖遮挡呢?—— 往控件上在套一层空内容的控件即可

内容缩放:

class ContentWidget(QWidget):
    def __init__(self,parent=None):
        super().__init__(parent)
        
        self.mainPage = MainPage(parent=self)
        
    def posAnimation(widget,x,y,s):
        move = QPropertyAnimation(widget, b'pos', parent=widget)
        move.setDuration(s)  # 设置动画时长,单位为毫秒
        move.setEndValue(QPoint(x, y))
        move.start()

    def topScale(self,bl:bool=True):
        if bl:
            # 向上
            posAnimation(self.mainPage, 0, -self.mainPage.height(), self.mainPage.height())
        else:
            # 向下
            posAnimation(self.mainPage, 0, 0, self.mainPage.height())
            
class mainPage(QWidget):
    def __init__(self,parent=None):
    	super().__init__(parent)
    ......

上述代码为基本原理,下面我们开始探索动画如何开始图标位置纠正

动画开始:

观察上图,可以发现窗口到屏幕侧一定距离并且鼠标离开界面收缩动画才会触发
所以重写离开事件鼠标事件

def mouseMoveEvent(self, event: QMouseEvent) -> None:
    super().mouseMoveEvent(event)

    if topLeftPos.x() <= 50:
        self._inLeft = True
    elif bottomRightPos.x() >= self.screenWidth - 50:
        self._inRight = True
    else:
        self._inLeft = False
        self._inRight = False

def leaveEvent(self, event):
    super().leaveEvent(event)

    if self._inLeft:
        print('窗口在左侧收缩动画')

    elif self._inRight:
        sprint('窗口在右侧收缩动画')

    elif not self._inLeft and not self._inRight:
        print('窗口复原')

图标纠正:

在计算机几何坐标中 原点:屏幕的左上角,最左侧的X坐标都为0,最右侧的X坐标为屏幕宽带最大值
而我们的图标分为以下两种情况:

  • 左侧:左上角顶点 (0 , y)
  • 右侧:左上角顶点 (screen_x - window_width , y)

纵坐标y 实际为窗口当前纵坐标,不需要做处理

def scaleOutMove(self,bl):
    if bl: # 左侧过渡动画
        move = QPropertyAnimation(self, b'pos', parent=self)
        move.setStartValue(QPoint(
            -self.icon.width(), 
            self.pos().y()
        ))
        move.setEndValue(QPoint(0, self.pos().y()))
        move.start()
    else: # 右侧过渡动画
        move = QPropertyAnimation(self, b'pos', parent=self)
        move.setEndValue(QPoint(
            self.screenWidth - self.icon.width(), 
            self.pos().y()
        ))
        move.start()

左侧动画

左侧动画

右侧动画
右侧动画

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值