PySide2音乐播放专辑图片旋转效果
作者:YXN-python 阅读量:19 发布日期:2024-11-05
import sys
from io import BytesIO
import requests
from PySide2.QtCore import Qt, QTimer, Signal
from PySide2.QtGui import QPainter, QPixmap, QPainterPath
from PySide2.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton
class AlbumRotatingIcon(QWidget):
album_clicked = Signal(str)
def __init__(self, parent=None, bg_img_path='', album_img_path='', size=64, diff_size=20):
super(AlbumRotatingIcon, self).__init__(parent)
self.size = size
self.diff_size = diff_size
# 加载背景图片
self.bg_img = QPixmap(bg_img_path).scaled(
size, size, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation
)
# 加载并处理前景图片
self.album_img = self.prepare_album_image(album_img_path)
self.angle = 0
self.timer = QTimer(self)
self.timer.timeout.connect(self.rotateDisc)
self.timer.start(50) # 每50毫秒更新
self.setMinimumSize(size, size)
self.is_rotating = True # 用于跟踪当前旋转状态
def prepare_album_image(self, album_img_path):
album_img = QPixmap(album_img_path)
# 计算前景图片的最短边
min_side = min(album_img.width(), album_img.height())
# 使用裁剪区域定义一个正方形区域
x_offset = (album_img.width() - min_side) // 2
y_offset = (album_img.height() - min_side) // 2
cropped_pixmap = album_img.copy(x_offset, y_offset, min_side, min_side)
# 将裁剪后的正方形图像缩放来适应小圈(size-20)的大小
return cropped_pixmap.scaled(
self.size - self.diff_size, self.size - self.diff_size,
Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation
)
# 更新图片
def up_img(self, img):
"""
支持三种方式
1、网络图片地址 http://yixiuna.top/images/thumbnail/1726731481977697d044.jpg
2、本地图片地址 logo.ico
3、QPixmap加载的图片 QPixmap('logo.ico')
"""
try:
if isinstance(img, QPixmap):
self.album_img = self.prepare_album_image(img)
if isinstance(img, str):
if img.lower().startswith('http'):
self.album_img = self.prepare_album_image(self.load_image(img))
else:
self.album_img = self.prepare_album_image(img)
except Exception as e:
self.album_img = QPixmap()
# 加载网络图片
def load_image(self, url):
try:
response = requests.get(url)
img_data = BytesIO(response.content).getvalue()
pixmap = QPixmap()
pixmap.loadFromData(img_data)
return pixmap
except Exception as e:
pass
def pause(self):
"""暂停旋转"""
if self.is_rotating:
self.timer.stop()
self.is_rotating = False
def start(self):
"""启动旋转"""
if not self.is_rotating:
self.timer.start(50)
self.is_rotating = True
def rotateDisc(self):
self.angle = (self.angle + 1) % 360 # 每次旋转1度
self.update()
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.setRenderHint(QPainter.SmoothPixmapTransform)
# 中心点
center_x = self.width() / 2
center_y = self.height() / 2
# 绘制背景图,围绕自身中心旋转
painter.save()
painter.translate(center_x, center_y)
painter.rotate(self.angle)
painter.translate(-self.bg_img.width() / 2, -self.bg_img.height() / 2)
painter.drawPixmap(0, 0, self.bg_img)
painter.restore()
# 绘制前景图,围绕自身中心旋转
painter.save()
painter.translate(center_x, center_y)
painter.rotate(self.angle)
painter.translate(-self.album_img.width() / 2, -self.album_img.height() / 2)
# 创建一个圆形路径
path = QPainterPath()
path.addEllipse(0, 0, self.album_img.width(), self.album_img.height())
painter.setClipPath(path)
# 绘制被剪裁成圆形的前景图
painter.drawPixmap(0, 0, self.album_img)
painter.restore()
def mousePressEvent(self, event):
self.album_clicked.emit('这是一个信号')
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.rotating_disc = AlbumRotatingIcon(bg_img_path='../../img/record.ico',
album_img_path="../../img/logo.ico", size=64)
layout = QHBoxLayout()
layout.addWidget(self.rotating_disc)
bu = QPushButton('点击修改')
bu.clicked.connect(self.dd)
layout.addWidget(bu)
self.setLayout(layout)
self.setWindowTitle("Music Player")
def dd(self):
self.rotating_disc.up_img('../../img/empty.png')
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
效果图:
修改后:
YXN-python
2024-11-05