搅拌桨旋转(目前上料斗左移到搅拌楼下时触发)

This commit is contained in:
2025-11-06 19:03:56 +08:00
parent 75df5d79ef
commit 2b93713e7f
2 changed files with 144 additions and 28 deletions

View File

@ -197,6 +197,8 @@ class MainWindow(QWidget):
# 以下为模拟: # 以下为模拟:
# 假设两秒种之后,移动到了搅拌机下 (这里需要根据实际情况修改) # 假设两秒种之后,移动到了搅拌机下 (这里需要根据实际情况修改)
QTimer.singleShot(2000, self.conveyor_system_widget.moveHopperBelowMixer) QTimer.singleShot(2000, self.conveyor_system_widget.moveHopperBelowMixer)
# 移动到搅拌楼下,搅拌桨就开始旋转
QTimer.singleShot(2100, self.mixer_widget.startBladeMix)
# 料斗左移完成,恢复料斗右移按钮 # 料斗左移完成,恢复料斗右移按钮
QTimer.singleShot(2100, lambda: self.conveyor_system_widget.right_btn.setEnabled(True)) QTimer.singleShot(2100, lambda: self.conveyor_system_widget.right_btn.setEnabled(True))
@ -205,8 +207,12 @@ class MainWindow(QWidget):
# 演示效果 # 演示效果
self.conveyor_system_widget.moveHopperToTransition() # 移动到过渡的位置 self.conveyor_system_widget.moveHopperToTransition() # 移动到过渡的位置
self.hopper_widget.upper_clamp_widget.set_angle(0) # 上料斗向右移动到目的地时夹爪的角度一定是0 self.hopper_widget.upper_clamp_widget.set_angle(0) # 上料斗向右移动到目的地时夹爪的角度一定是0
# 按钮状态:点击料斗右移按钮后,禁用料斗左移按钮 # 按钮状态:点击料斗右移按钮后,禁用料斗左移按钮
self.conveyor_system_widget.left_btn.setEnabled(False) self.conveyor_system_widget.left_btn.setEnabled(False)
# 开始右移,搅拌桨就停止转动
self.mixer_widget.stopBladeMix()
# 以下为模拟: # 以下为模拟:
# 假设两秒后,传送带中 料斗向右移动完成 (这里需要根据实际情况修改) # 假设两秒后,传送带中 料斗向右移动完成 (这里需要根据实际情况修改)
QTimer.singleShot(1900, self.conveyor_system_widget.hideHopper) # 料斗向右移动完成,隐藏料斗 QTimer.singleShot(1900, self.conveyor_system_widget.hideHopper) # 料斗向右移动完成,隐藏料斗

View File

@ -1,14 +1,88 @@
from PySide6.QtWidgets import QWidget, QLabel, QHBoxLayout from PySide6.QtWidgets import QWidget, QLabel, QHBoxLayout
from PySide6.QtGui import QPixmap, QFont from PySide6.QtGui import QPixmap, QFont, QTransform
from PySide6.QtCore import Qt from PySide6.QtCore import Qt, QPropertyAnimation, QEasingCurve, Property
import resources.resources_rc import resources.resources_rc
from utils.image_paths import ImagePaths 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): class MixerWidget(QWidget):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
# 两个搅拌桨的转动的动画引用
self.animations = [] # 保存动画引用
# 初始化布局 # 初始化布局
layout = QHBoxLayout(self) layout = QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0)
@ -28,35 +102,71 @@ class MixerWidget(QWidget):
""") """)
layout.addWidget(self.text_label, alignment=Qt.AlignLeft) layout.addWidget(self.text_label, alignment=Qt.AlignLeft)
# 2. 创建搅拌机设备及搅拌桨图标 # 2. 创建搅拌机设备
self.device_label = QLabel() self.device_label = QLabel()
device_pixmap = QPixmap(ImagePaths.MIXER) device_pixmap = QPixmap(ImagePaths.MIXER)
self.device_label.setPixmap(device_pixmap) self.device_label.setPixmap(device_pixmap)
layout.addWidget(self.device_label, alignment=Qt.AlignLeft) layout.addWidget(self.device_label, alignment=Qt.AlignLeft)
# 3. 叠加两个搅拌桨图标 # 3. 初始化两个搅拌桨
self.blade1 = QLabel(self.device_label) # 从左往右第一个搅拌桨 self._init_blades()
blade1_pixmap = QPixmap(ImagePaths.MIXER_PADDLE)
self.blade1.setPixmap(blade1_pixmap)
self.blade1.move(
(device_pixmap.width() - blade1_pixmap.width()) // 2 - 26,
(device_pixmap.height() - blade1_pixmap.height()) // 2 - 4
)
self.blade2 = QLabel(self.device_label) def _init_blades(self):
blade2_pixmap = QPixmap(ImagePaths.MIXER_PADDLE) # 从左往右第二个搅拌桨 blade_pixmap = QPixmap(ImagePaths.MIXER_PADDLE)
self.blade2.setPixmap(blade2_pixmap) if blade_pixmap.isNull():
self.blade2.move( return
(device_pixmap.width() - blade2_pixmap.width()) // 2 + 31,
(device_pixmap.height() - blade2_pixmap.height()) // 2 - 4
)
# 测试代码 # 设备背景的尺寸(用于计算固定中心点)
if __name__ == "__main__": device_pixmap = self.device_label.pixmap()
import sys if not device_pixmap:
from PySide6.QtWidgets import QApplication, QMainWindow return
device_w = device_pixmap.width()
device_h = device_pixmap.height()
app = QApplication(sys.argv) # --------------------------
mixer_widget = MixerWidget() # 左搅拌桨:计算固定中心点
mixer_widget.show() # --------------------------
sys.exit(app.exec()) 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):
self.animations.clear()
# 备注duration控制搅拌桨旋转的速度值越小旋转得越快
self._start_animation(self.blade1, duration)
self._start_animation(self.blade2, duration)
def stopBladeMix(self):
for animation in self.animations:
animation.stop()
if self.blade1:
self.blade1.reset_to_original()
if self.blade2:
self.blade2.reset_to_original()