PyQt/QPropertyAnimation/Lib/FlipWidget.py

122 lines
4.4 KiB
Python
Raw Normal View History

2019-05-15 22:19:29 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2019年5月15日
@author: Irony
@site: https://pyqt5.com https://github.com/892768447
@email: 892768447@qq.com
@file: FlipWidget
@description: 动画翻转窗口
"""
from PyQt5.QtCore import pyqtSignal, Qt, QPropertyAnimation, QEasingCurve,\
pyqtProperty, QPointF
from PyQt5.QtGui import QPainter, QTransform
from PyQt5.QtWidgets import QWidget
__Author__ = 'Irony'
__Copyright__ = 'Copyright (c) 2019'
class FlipWidget(QWidget):
Left = 0 # 从右往左
Right = 1 # 从左往右
Scale = 3 # 图片缩放比例
finished = pyqtSignal()
def __init__(self, *args, **kwargs):
super(FlipWidget, self).__init__(*args, **kwargs)
# 无边框无任务栏
self.setWindowFlags(self.windowFlags() |
Qt.FramelessWindowHint | Qt.SubWindow)
# 背景透明
self.setAttribute(Qt.WA_TranslucentBackground, True)
# 翻转角度
self._angle = 0
# 属性动画针对自定义属性`angle`
self._animation = QPropertyAnimation(self, b'angle', self)
self._animation.setDuration(550)
self._animation.setEasingCurve(QEasingCurve.OutInQuad)
self._animation.finished.connect(self.finished.emit)
@pyqtProperty(int)
def angle(self):
return self._angle
@angle.setter
def angle(self, angle):
self._angle = angle
self.update()
def updateImages(self, direction, image1, image2):
"""设置两张切换图
:param direction: 方向
:param image1: 图片1
:param image2: 图片2
"""
self.image1 = image1
self.image2 = image2
self.show()
self._angle = 0
# 根据方向设置动画的初始和结束值
if direction == self.Right:
self._animation.setStartValue(1)
self._animation.setEndValue(-180)
elif direction == self.Left:
self._animation.setStartValue(1)
self._animation.setEndValue(180)
self._animation.start()
def paintEvent(self, event):
super(FlipWidget, self).paintEvent(event)
if hasattr(self, 'image1') and hasattr(self, 'image2') and self.isVisible():
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing, True)
painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
# 变换
transform = QTransform()
# 把圆心设置为矩形中心
transform.translate(self.width() / 2, self.height() / 2)
if self._angle >= -90 and self._angle <= 90:
# 当翻转角度在90范围内显示第一张图且从大图缩放到小图的过程
painter.save()
# 设置翻转角度
transform.rotate(self._angle, Qt.YAxis)
painter.setTransform(transform)
# 缩放图片高度
width = self.image1.width() / 2
height = int(self.image1.height() *
(1 - abs(self._angle / self.Scale) / 100))
image = self.image1.scaled(
self.image1.width(), height,
Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
painter.drawPixmap(
QPointF(-width, -height / 2), image)
painter.restore()
else:
# 当翻转角度在90范围内显示第二张图且从小图缩放到原图的过程
painter.save()
if self._angle > 0:
angle = 180 + self._angle
else:
angle = self._angle - 180
# 设置翻转角度, 注意这里角度有差异
transform.rotate(angle, Qt.YAxis)
painter.setTransform(transform)
# 缩放图片高度
width = self.image2.width() / 2
height = int(self.image2.height() *
(1 - ((360 - abs(angle)) / self.Scale / 100)))
image = self.image2.scaled(
self.image2.width(), height,
Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
painter.drawPixmap(
QPointF(-width, -height / 2), image)
painter.restore()