Files
Feeding_control_system/view/widgets/mixer_widget.py

186 lines
7.8 KiB
Python
Raw 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.

from PySide6.QtWidgets import QWidget, QLabel, QHBoxLayout
from PySide6.QtGui import QPixmap, QFont, QTransform
from PySide6.QtCore import Qt, QPropertyAnimation, QEasingCurve, Property
import resources.resources_rc
from utils.image_paths import ImagePaths
class BladeLabel(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
self._rotation = 0.0
self._original_pixmap = None
self._original_center_x = 0.0 # 原始图片自身中心点x
self._original_center_y = 0.0 # 原始图片自身中心点y
self._fixed_center_in_parent_x = 0 # 父容器中的固定中心点x关键
self._fixed_center_in_parent_y = 0 # 父容器中的固定中心点y关键
# self.setFixedSize(50, 54)
def set_original_pixmap(self, pixmap, fixed_center_x, fixed_center_y):
"""
:param pixmap: 原始图片
:param fixed_center_x: 父容器中固定的中心点x坐标绝对位置
:param fixed_center_y: 父容器中固定的中心点y坐标绝对位置
"""
self._original_pixmap = pixmap
if pixmap.isNull():
print("错误:搅拌桨图片加载失败!")
return
# 记录原始图片自身的中心点(用于旋转计算)
self._original_center_x = 28 # 图片的中心点为 28,28
self._original_center_y = 28
# 记录在父容器中的固定中心点(旋转时始终对齐这个点)
self._fixed_center_in_parent_x = fixed_center_x
self._fixed_center_in_parent_y = fixed_center_y
# 初始显示图片
self.setPixmap(pixmap)
# 初始位置:让原始图片的中心点与固定中心点对齐
self._update_position(pixmap.width(), pixmap.height())
def _update_position(self, current_w, current_h):
"""根据当前图片尺寸,计算位置使中心点与固定坐标对齐"""
# 当前图片的中心点坐标(自身坐标系)
current_center_x = current_w / 2
current_center_y = current_h / 2
# 计算左上角坐标:固定中心点 - 当前图片中心点
x = self._fixed_center_in_parent_x - current_center_x
y = self._fixed_center_in_parent_y - current_center_y
self.move(round(x), round(y)) # 取整避免浮点数位置偏差
self.setFixedSize(current_w, current_h)
def get_rotation(self):
return self._rotation
def set_rotation(self, angle):
self._rotation = angle
if self._original_pixmap is None:
return
# 生成旋转后的图片(保持旋转中心为原始图片中心)
transform = QTransform()
transform.translate(self._original_center_x, self._original_center_y)
transform.rotate(angle)
transform.translate(-self._original_center_x, -self._original_center_y)
rotated_pixmap = self._original_pixmap.transformed(transform, Qt.SmoothTransformation)
# 强制对齐固定中心点(关键:无论尺寸如何变化,中心点不变)
self._update_position(rotated_pixmap.width(), rotated_pixmap.height())
self.setPixmap(rotated_pixmap)
rotation = Property(float, get_rotation, set_rotation)
def reset_to_original(self):
self._rotation = 0.0 # 重置旋转角度为0°
if self._original_pixmap is not None:
self.setPixmap(self._original_pixmap) # 恢复原始图片
# 恢复初始位置(基于原始图片尺寸)
self._update_position(self._original_pixmap.width(), self._original_pixmap.height())
class MixerWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
# 状态变量:标记搅拌桨是否正在旋转
self.is_mixing = False # 初始状态为未旋转
# 两个搅拌桨的转动的动画引用
self.animations = [] # 保存动画引用
# 初始化布局
layout = QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
self.setFixedSize(225, 102)
# 1. 创建“搅拌机”文字标签
self.text_label = QLabel("搅拌机")
self.text_label.setFixedSize(100, 23)
self.text_label.setFont(QFont("Arial", 14)) # 设置字体大小为16px
self.text_label.setAlignment(Qt.AlignCenter)
self.text_label.setStyleSheet(f"""
background-image: url({ImagePaths.TEXT_TITLE_BG});
background-repeat: no-repeat;
background-position: center;
color: #0bffff; /* 可根据需求调整文字颜色 */
""")
layout.addWidget(self.text_label, alignment=Qt.AlignLeft)
# 2. 创建搅拌机设备
self.device_label = QLabel()
device_pixmap = QPixmap(ImagePaths.MIXER)
self.device_label.setPixmap(device_pixmap)
layout.addWidget(self.device_label, alignment=Qt.AlignLeft)
# 3. 初始化两个搅拌桨
self._init_blades()
def _init_blades(self):
blade_pixmap = QPixmap(ImagePaths.MIXER_PADDLE)
if blade_pixmap.isNull():
return
# 设备背景的尺寸(用于计算固定中心点)
device_pixmap = self.device_label.pixmap()
if not device_pixmap:
return
device_w = device_pixmap.width()
device_h = device_pixmap.height()
# --------------------------
# 左搅拌桨:计算固定中心点
# --------------------------
left_center_x = (device_w // 2) - 26 # 左桨中心点x示例值需根据实际调整
left_center_y = device_h // 2 - 5 # 左桨中心点y示例值需根据实际调整
self.blade1 = BladeLabel(self.device_label)
self.blade1.set_original_pixmap(blade_pixmap, left_center_x, left_center_y)
# --------------------------
# 右搅拌桨:计算固定中心点
# --------------------------
right_center_x = (device_w // 2) + 30 # 右桨中心点x示例值需根据实际调整
right_center_y = device_h // 2 - 5 # 右桨中心点y与左桨对齐
self.blade2 = BladeLabel(self.device_label)
self.blade2.set_original_pixmap(blade_pixmap, right_center_x, right_center_y)
def _start_animation(self, blade: BladeLabel, duration: int, reverse: bool = False):
"""
Args:
blade: 所需旋转的搅拌桨标签
duration 一次搅拌桨旋转所需的时间,值越小,旋转越快
reverse: 是否反转(逆时针转)
"""
animation = QPropertyAnimation(blade, b"rotation")
animation.setStartValue(360 if reverse else 0)
animation.setEndValue(0 if reverse else 360)
animation.setDuration(duration)
animation.setEasingCurve(QEasingCurve.Linear)
animation.setLoopCount(-1)
self.animations.append(animation)
animation.start()
# 搅拌桨开始搅拌
def startBladeMix(self, duration=700):
if self.is_mixing: # 搅拌桨已经在旋转
return
self.animations.clear()
# 备注duration控制搅拌桨旋转的速度值越小旋转得越快
self._start_animation(self.blade1, duration)
self._start_animation(self.blade2, duration)
self.is_mixing = True # 更新搅拌桨状态为旋转中
def stopBladeMix(self):
if not self.is_mixing: # 搅拌桨已经停止
return
for animation in self.animations:
animation.stop()
if self.blade1:
self.blade1.reset_to_original()
if self.blade2:
self.blade2.reset_to_original()
self.is_mixing = False # 更新搅拌桨状态为停止