PyQt/QPropertyAnimation/Lib/FlipWidget.py
2021-07-13 14:52:26 +08:00

122 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created on 2019年5月15日
@author: Irony
@site: https://pyqt.site , https://github.com/PyQt5
@email: 892768447@qq.com
@file: FlipWidget
@description: 动画翻转窗口
"""
try:
from PyQt5.QtCore import pyqtSignal, pyqtProperty, Qt, QPropertyAnimation, QEasingCurve, QPointF
from PyQt5.QtGui import QPainter, QTransform
from PyQt5.QtWidgets import QWidget
except ImportError:
from PySide2.QtCore import Signal as pyqtSignal, Property as pyqtProperty, Qt, QPropertyAnimation, \
QEasingCurve, QPointF
from PySide2.QtGui import QPainter, QTransform
from PySide2.QtWidgets import QWidget
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()