2025-10-18 18:29:40 +08:00
|
|
|
|
from PySide6.QtWidgets import (QApplication, QWidget, QPushButton, QLabel,
|
|
|
|
|
|
QVBoxLayout, QHBoxLayout)
|
|
|
|
|
|
from PySide6.QtGui import QPainter, QColor, QFont, QPixmap, Qt, QBrush
|
|
|
|
|
|
from PySide6.QtCore import QPoint, Signal, Slot
|
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|
|
# 圆形按钮
|
|
|
|
|
|
from .circular_button import CircularButton
|
|
|
|
|
|
|
2025-10-31 18:52:31 +08:00
|
|
|
|
from .clamp_widget import ClampWidget
|
|
|
|
|
|
|
|
|
|
|
|
import resources.resources_rc
|
2025-11-01 16:13:14 +08:00
|
|
|
|
from utils.image_paths import ImagePaths
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
|
|
|
|
|
class HopperWidget(QWidget):
|
|
|
|
|
|
# 上料斗破拱信号
|
|
|
|
|
|
# 开启破拱 True,关闭破拱 False
|
|
|
|
|
|
upper_arch_breaking_signal = Signal(bool)
|
|
|
|
|
|
|
|
|
|
|
|
# 下料斗破拱信号
|
|
|
|
|
|
# 开启破拱 True,关闭破拱 False
|
|
|
|
|
|
lower_arch_breaking_signal = Signal(bool)
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
|
super().__init__()
|
|
|
|
|
|
self.setWindowTitle("料斗控制界面")
|
|
|
|
|
|
|
|
|
|
|
|
# 破拱状态 (True/False)
|
|
|
|
|
|
self.upper_arch_breaking_status = False # 初始为不破拱状态
|
|
|
|
|
|
self.lower_arch_breaking_status = False # 初始为不破拱状态
|
|
|
|
|
|
|
2025-11-06 15:10:58 +08:00
|
|
|
|
# 上一次获取到的料斗的当前重量
|
|
|
|
|
|
self._last_upper_hopper_weight = None # 上一次的上料斗重量(初始为None)
|
|
|
|
|
|
self._last_lower_hopper_weight = None # 上一次的下料斗重量(初始为None)
|
|
|
|
|
|
|
2025-10-18 18:29:40 +08:00
|
|
|
|
# 料斗控制界面的固定大小为 332x482,
|
|
|
|
|
|
# 需要根据具体的料斗的图片来调整
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# self.setFixedSize(356, 496)
|
|
|
|
|
|
self.setFixedSize(356, 516)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
|
|
|
|
|
# 创建上位和下位料斗
|
|
|
|
|
|
self.upper_hopper = self.create_upper_hopper()
|
|
|
|
|
|
self.lower_hopper = self.create_lower_hopper()
|
|
|
|
|
|
|
|
|
|
|
|
# 主布局
|
|
|
|
|
|
main_layout = QVBoxLayout(self)
|
|
|
|
|
|
main_layout.addWidget(self.upper_hopper)
|
|
|
|
|
|
main_layout.addWidget(self.lower_hopper)
|
|
|
|
|
|
main_layout.setSpacing(0)
|
|
|
|
|
|
main_layout.setContentsMargins(10, 10, 0, 10)
|
|
|
|
|
|
|
|
|
|
|
|
self.connectSignalToSlot()
|
|
|
|
|
|
|
|
|
|
|
|
def create_upper_hopper(self):
|
|
|
|
|
|
"""创建上位料斗Widget"""
|
|
|
|
|
|
group = QWidget()
|
|
|
|
|
|
|
|
|
|
|
|
# 上位的 料斗控件的固定尺寸 !!!!
|
|
|
|
|
|
# 注意: 这里需要根据具体的料斗图片来修改
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# group.setFixedSize(332, 202)
|
|
|
|
|
|
group.setFixedSize(332, 222) # 调整!!
|
2025-10-18 18:29:40 +08:00
|
|
|
|
# group.setStyleSheet("background-color: green")
|
|
|
|
|
|
|
|
|
|
|
|
layout = QVBoxLayout(group)
|
|
|
|
|
|
layout.setSpacing(0)
|
|
|
|
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
|
|
|
|
|
|
|
# 标题标签(上位)
|
|
|
|
|
|
self.upper_title_label = QLabel("上位料斗")
|
2025-10-31 18:52:31 +08:00
|
|
|
|
self.upper_title_label.setFixedSize(117, 23)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.upper_title_label.setAlignment(Qt.AlignCenter)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# self.upper_title_label.setStyleSheet("color: #2fd3f2; font-size: 14px; font-weight: bold;")
|
|
|
|
|
|
# self.upper_title_label.setStyleSheet("color: #0bffff; font-size: 18px;")
|
2025-11-01 16:13:14 +08:00
|
|
|
|
self.upper_title_label.setStyleSheet(f"""
|
2025-10-31 18:52:31 +08:00
|
|
|
|
color: #0bffff;
|
|
|
|
|
|
font-size: 18px;
|
2025-11-01 16:13:14 +08:00
|
|
|
|
background-image: url({ImagePaths.TEXT_TITLE_BG});
|
2025-10-31 18:52:31 +08:00
|
|
|
|
background-repeat: no-repeat;
|
|
|
|
|
|
background-position: center;
|
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
|
""")
|
2025-10-18 18:29:40 +08:00
|
|
|
|
layout.addWidget(self.upper_title_label, alignment=Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
|
|
# 加载外框图片
|
2025-11-01 16:13:14 +08:00
|
|
|
|
outer_img = ImagePaths.HOPPER1
|
2025-10-18 18:29:40 +08:00
|
|
|
|
outer_pixmap = QPixmap(outer_img)
|
|
|
|
|
|
if outer_pixmap.isNull():
|
|
|
|
|
|
print(f"警告:图片 {outer_img} 加载失败,请检查路径!")
|
|
|
|
|
|
return group
|
|
|
|
|
|
outer_width = outer_pixmap.width()
|
|
|
|
|
|
outer_height = outer_pixmap.height()
|
|
|
|
|
|
|
|
|
|
|
|
# 背景容器(上位)
|
|
|
|
|
|
self.upper_bg_widget = QWidget()
|
|
|
|
|
|
self.upper_bg_widget.setFixedSize(outer_width, outer_height)
|
2025-11-06 10:55:29 +08:00
|
|
|
|
self.upper_bg_widget.setStyleSheet(f"background-image: url({outer_img});background-repeat: no-repeat; background-position: center;")
|
|
|
|
|
|
# self.upper_bg_widget.setStyleSheet(f"background-color:red; background-repeat: no-repeat; background-position: center;")
|
2025-10-18 18:29:40 +08:00
|
|
|
|
layout.addWidget(self.upper_bg_widget, alignment=Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
|
|
# 内框图片(上位)
|
2025-11-01 16:13:14 +08:00
|
|
|
|
inner_img = ImagePaths.HOPPER2
|
2025-10-18 18:29:40 +08:00
|
|
|
|
inner_pixmap = QPixmap(inner_img)
|
|
|
|
|
|
if not inner_pixmap.isNull():
|
|
|
|
|
|
self.upper_inner_label = QLabel(self.upper_bg_widget)
|
|
|
|
|
|
self.upper_inner_label.setPixmap(inner_pixmap)
|
2025-11-06 10:55:29 +08:00
|
|
|
|
self.upper_inner_label.setFixedSize(inner_pixmap.width(), inner_pixmap.height()) # 初始宽高
|
|
|
|
|
|
self.upper_inner_label.setScaledContents(False) # 禁用缩放(避免图片拉伸)
|
|
|
|
|
|
self.upper_inner_label.setStyleSheet("background: none;")
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.upper_inner_label.move(14, 9)
|
2025-11-06 10:55:29 +08:00
|
|
|
|
self.upper_inner_label.setAlignment(Qt.AlignBottom)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
|
|
|
|
|
# 状态图片(上位,绿色)
|
2025-11-01 16:13:14 +08:00
|
|
|
|
status_img = ImagePaths.HOPPER_STATUS_GREEN
|
2025-10-18 18:29:40 +08:00
|
|
|
|
status_pixmap = QPixmap(status_img)
|
|
|
|
|
|
if not status_pixmap.isNull():
|
2025-10-31 18:52:31 +08:00
|
|
|
|
status_pixmap = status_pixmap.scaled(13, 13, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.upper_status_label = QLabel(self.upper_bg_widget)
|
|
|
|
|
|
self.upper_status_label.setPixmap(status_pixmap)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
self.upper_status_label.move(22, 12)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.upper_status_label.setScaledContents(False)
|
|
|
|
|
|
self.upper_status_label.setStyleSheet("background: none;")
|
|
|
|
|
|
|
|
|
|
|
|
# 破拱图片(上位)
|
2025-11-01 16:13:14 +08:00
|
|
|
|
arch_img = ImagePaths.ARCH_BREAK
|
2025-10-18 18:29:40 +08:00
|
|
|
|
arch_pixmap = QPixmap(arch_img)
|
|
|
|
|
|
if not arch_pixmap.isNull():
|
2025-10-31 18:52:31 +08:00
|
|
|
|
arch_pixmap = arch_pixmap.scaled(16, 13, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.upper_arch_label = QLabel(self.upper_bg_widget)
|
|
|
|
|
|
self.upper_arch_label.setPixmap(arch_pixmap)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
self.upper_arch_label.move(outer_width - 39, 12)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.upper_arch_label.setStyleSheet("background: none;")
|
|
|
|
|
|
self.upper_arch_label.setHidden(True) # 初始,不破拱状态,隐藏
|
|
|
|
|
|
|
|
|
|
|
|
# 重量文字(上位)
|
|
|
|
|
|
self.upper_weight_label = QLabel("5000kg", self.upper_bg_widget)
|
|
|
|
|
|
self.upper_weight_label.setAlignment(Qt.AlignCenter)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
self.upper_weight_label.setStyleSheet("background: none; background-color: #003669; color: #16ffff; font-size: 18px;")
|
|
|
|
|
|
# self.upper_weight_label.setFixedSize(93, 22)
|
|
|
|
|
|
self.upper_weight_label.setFixedSize(120, 29)
|
|
|
|
|
|
self.upper_weight_label.move(outer_width//2 - 60, outer_height//2 - 46)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
|
|
|
|
|
# 额外文字(上位)
|
|
|
|
|
|
self.upper_extra_label = QLabel("2.0方(预估)", self.upper_bg_widget)
|
|
|
|
|
|
self.upper_extra_label.setAlignment(Qt.AlignCenter)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# #262c38 #16ffff #131427 #003669
|
|
|
|
|
|
self.upper_extra_label.setStyleSheet("background: none; background-color: #003669; color: #16ffff; font-size: 18px;")
|
|
|
|
|
|
self.upper_extra_label.setFixedSize(120, 29)
|
|
|
|
|
|
self.upper_extra_label.move(outer_width//2 - 60, outer_height//2 - 13)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# 夹具容器
|
|
|
|
|
|
self.upper_clamp_widget = ClampWidget()
|
|
|
|
|
|
layout.addWidget(self.upper_clamp_widget, alignment=Qt.AlignCenter)
|
|
|
|
|
|
self.upper_bg_widget.raise_() # 夹具图层位于 upper_bg_widget之下
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# 按钮(上位料斗)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.upper_open_btn = CircularButton("开", group)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# self.upper_open_btn.move(60, 153) # 上位料斗的开按钮位置
|
|
|
|
|
|
self.upper_open_btn.move(290, 90)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# self.upper_close_btn = CircularButton("关", group)
|
|
|
|
|
|
# self.upper_close_btn.move(233, 153) # 上位料斗的关按钮位置
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
|
|
|
|
|
self.upper_arch_btn = CircularButton("拱", group)
|
|
|
|
|
|
self.upper_arch_btn.move(290, 37) # 上位料斗的破拱按钮位置
|
|
|
|
|
|
|
|
|
|
|
|
return group
|
|
|
|
|
|
|
|
|
|
|
|
def connectSignalToSlot(self):
|
|
|
|
|
|
self.upper_arch_btn.clicked.connect(self.onUpperArchBreaking)
|
|
|
|
|
|
self.lower_arch_btn.clicked.connect(self.onLowerArchBreaking)
|
|
|
|
|
|
|
|
|
|
|
|
@Slot()
|
|
|
|
|
|
def onUpperArchBreaking(self):
|
|
|
|
|
|
if self.upper_arch_breaking_status == False: # 不破拱状态
|
|
|
|
|
|
# 此时,点击按钮为开启破拱
|
|
|
|
|
|
self.upper_arch_breaking_status = True
|
|
|
|
|
|
self.upper_arch_label.setHidden(False)
|
|
|
|
|
|
self.upper_arch_breaking_signal.emit(self.upper_arch_breaking_status)
|
|
|
|
|
|
else: # 破拱状态
|
|
|
|
|
|
# 此时,点击按钮为关闭破拱
|
|
|
|
|
|
self.upper_arch_breaking_status = False
|
|
|
|
|
|
self.upper_arch_label.setHidden(True)
|
|
|
|
|
|
self.upper_arch_breaking_signal.emit(self.upper_arch_breaking_status)
|
|
|
|
|
|
|
|
|
|
|
|
@Slot()
|
|
|
|
|
|
def onLowerArchBreaking(self):
|
|
|
|
|
|
if self.lower_arch_breaking_status == False: # 不破拱状态
|
|
|
|
|
|
# 此时,点击按钮为开启破拱
|
|
|
|
|
|
self.lower_arch_breaking_status = True
|
|
|
|
|
|
self.lower_arch_label.setHidden(False)
|
|
|
|
|
|
self.lower_arch_breaking_signal.emit(self.lower_arch_breaking_status)
|
|
|
|
|
|
else: # 破拱状态
|
|
|
|
|
|
# 此时,点击按钮为关闭破拱
|
|
|
|
|
|
self.lower_arch_breaking_status = False
|
|
|
|
|
|
self.lower_arch_label.setHidden(True)
|
|
|
|
|
|
self.upper_arch_breaking_signal.emit(self.lower_arch_breaking_status)
|
|
|
|
|
|
|
|
|
|
|
|
def create_lower_hopper(self):
|
|
|
|
|
|
"""创建下位料斗Widget"""
|
|
|
|
|
|
group = QWidget()
|
|
|
|
|
|
|
|
|
|
|
|
# 下位的 料斗控件的固定尺寸 !!!!
|
|
|
|
|
|
# 注意: 这里需要根据具体的料斗图片来修改
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# group.setFixedSize(332, 280)
|
|
|
|
|
|
group.setFixedSize(332, 222)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
# group.setStyleSheet("background-color: black")
|
|
|
|
|
|
|
|
|
|
|
|
layout = QVBoxLayout(group)
|
|
|
|
|
|
layout.setSpacing(0)
|
|
|
|
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
|
|
|
|
|
|
|
# 标题标签(下位)
|
|
|
|
|
|
self.lower_title_label = QLabel("低位料斗")
|
2025-10-31 18:52:31 +08:00
|
|
|
|
self.lower_title_label.setFixedSize(117, 23)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.lower_title_label.setAlignment(Qt.AlignCenter)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# self.lower_title_label.setStyleSheet("color: #2fd3f2; font-size: 14px; font-weight: bold;")
|
|
|
|
|
|
# self.lower_title_label.setStyleSheet("color: #0bffff; font-size: 18px;")
|
2025-11-01 16:13:14 +08:00
|
|
|
|
self.lower_title_label.setStyleSheet(f"""
|
2025-10-31 18:52:31 +08:00
|
|
|
|
color: #0bffff;
|
|
|
|
|
|
font-size: 18px;
|
2025-11-01 16:13:14 +08:00
|
|
|
|
background-image: url({ImagePaths.TEXT_TITLE_BG});
|
2025-10-31 18:52:31 +08:00
|
|
|
|
background-repeat: no-repeat;
|
|
|
|
|
|
background-position: center;
|
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
|
""")
|
2025-10-18 18:29:40 +08:00
|
|
|
|
layout.addWidget(self.lower_title_label, alignment=Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
|
|
# 加载外框图片
|
2025-11-01 16:13:14 +08:00
|
|
|
|
outer_img = ImagePaths.HOPPER1
|
2025-10-18 18:29:40 +08:00
|
|
|
|
outer_pixmap = QPixmap(outer_img)
|
|
|
|
|
|
if outer_pixmap.isNull():
|
|
|
|
|
|
print(f"警告:图片 {outer_img} 加载失败,请检查路径!")
|
|
|
|
|
|
return group
|
|
|
|
|
|
outer_width = outer_pixmap.width()
|
|
|
|
|
|
outer_height = outer_pixmap.height()
|
|
|
|
|
|
|
|
|
|
|
|
# 背景容器(下位)
|
|
|
|
|
|
self.lower_bg_widget = QWidget()
|
|
|
|
|
|
self.lower_bg_widget.setFixedSize(outer_width, outer_height)
|
|
|
|
|
|
self.lower_bg_widget.setStyleSheet(f"background-image: url({outer_img}); background-repeat: no-repeat; background-position: center;")
|
|
|
|
|
|
layout.addWidget(self.lower_bg_widget, alignment=Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
|
|
# 内框图片(下位)
|
2025-11-01 16:13:14 +08:00
|
|
|
|
inner_img = ImagePaths.HOPPER2
|
2025-10-18 18:29:40 +08:00
|
|
|
|
inner_pixmap = QPixmap(inner_img)
|
|
|
|
|
|
if not inner_pixmap.isNull():
|
|
|
|
|
|
self.lower_inner_label = QLabel(self.lower_bg_widget)
|
|
|
|
|
|
self.lower_inner_label.setPixmap(inner_pixmap)
|
|
|
|
|
|
self.lower_inner_label.setFixedSize(inner_pixmap.width(), inner_pixmap.height())
|
2025-11-06 10:55:29 +08:00
|
|
|
|
self.lower_inner_label.setScaledContents(False) # 禁用图片缩放
|
|
|
|
|
|
self.lower_inner_label.setStyleSheet("background: none;")
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.lower_inner_label.move(14, 9)
|
2025-11-06 10:55:29 +08:00
|
|
|
|
self.lower_inner_label.setAlignment(Qt.AlignBottom)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# 状态图片(下位)
|
2025-11-01 16:13:14 +08:00
|
|
|
|
status_img = ImagePaths.HOPPER_STATUS_GREEN
|
2025-10-18 18:29:40 +08:00
|
|
|
|
status_pixmap = QPixmap(status_img)
|
|
|
|
|
|
if not status_pixmap.isNull():
|
2025-10-31 18:52:31 +08:00
|
|
|
|
status_pixmap = status_pixmap.scaled(13, 13, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.lower_status_label = QLabel(self.lower_bg_widget)
|
|
|
|
|
|
self.lower_status_label.setPixmap(status_pixmap)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
self.lower_status_label.move(22, 12)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.lower_status_label.setScaledContents(False)
|
|
|
|
|
|
self.lower_status_label.setStyleSheet("background: none;")
|
|
|
|
|
|
|
|
|
|
|
|
# 破拱图片(下位)
|
2025-11-01 16:13:14 +08:00
|
|
|
|
arch_img = ImagePaths.ARCH_BREAK
|
2025-10-18 18:29:40 +08:00
|
|
|
|
arch_pixmap = QPixmap(arch_img)
|
|
|
|
|
|
if not arch_pixmap.isNull():
|
2025-10-31 18:52:31 +08:00
|
|
|
|
arch_pixmap = arch_pixmap.scaled(16, 13, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.lower_arch_label = QLabel(self.lower_bg_widget)
|
|
|
|
|
|
self.lower_arch_label.setPixmap(arch_pixmap)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
self.lower_arch_label.move(outer_width - 39, 12)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.lower_arch_label.setStyleSheet("background: none;")
|
|
|
|
|
|
self.lower_arch_label.setHidden(True) # 初始,不破拱状态,隐藏
|
|
|
|
|
|
|
|
|
|
|
|
# 重量文字(下位)
|
|
|
|
|
|
self.lower_weight_label = QLabel("5000kg", self.lower_bg_widget)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# self.lower_weight_label.setStyleSheet("background: none; background-color: #262c38; color: #79c053; font-size: 14px;font-weight: bold;")
|
|
|
|
|
|
self.lower_weight_label.setStyleSheet("background: none; background-color: #003669; color: #16ffff; font-size: 18px;")
|
2025-10-18 18:29:40 +08:00
|
|
|
|
self.lower_weight_label.setAlignment(Qt.AlignCenter)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# self.lower_weight_label.setFixedSize(93, 22)
|
|
|
|
|
|
self.lower_weight_label.setFixedSize(120, 29)
|
|
|
|
|
|
# self.lower_weight_label.move(outer_width//2 - 46, outer_height//2 - 46)
|
|
|
|
|
|
self.lower_weight_label.move(outer_width//2 - 60, outer_height//2 - 46)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
|
|
|
|
|
# 额外文字(下位)
|
|
|
|
|
|
self.lower_extra_label = QLabel("开: 25°", self.lower_bg_widget)
|
|
|
|
|
|
self.lower_extra_label.setAlignment(Qt.AlignCenter)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# self.lower_extra_label.setStyleSheet("background: none; background-color: #262c38; color: #79c053; font-size: 14px;font-weight: bold;")
|
|
|
|
|
|
self.lower_extra_label.setStyleSheet("background: none; background-color: #003669; color: #16ffff; font-size: 18px;")
|
|
|
|
|
|
# self.lower_extra_label.setFixedSize(93, 22)
|
|
|
|
|
|
self.lower_extra_label.setFixedSize(120, 29)
|
|
|
|
|
|
# self.lower_extra_label.move(outer_width//2 - 46, outer_height//2 - 20)
|
|
|
|
|
|
self.lower_extra_label.move(outer_width//2 - 60, outer_height//2 - 13)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# 夹具容器
|
|
|
|
|
|
self.lower_clamp_widget = ClampWidget()
|
|
|
|
|
|
layout.addWidget( self.lower_clamp_widget, alignment=Qt.AlignCenter)
|
|
|
|
|
|
self.lower_bg_widget.raise_() # 夹具图层位于 self.lower_bg_widget之下
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
|
|
|
|
|
# 按钮(下位)
|
|
|
|
|
|
self.lower_open_btn = CircularButton("开", group)
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# self.lower_open_btn.move(60, 233) # 下位料斗的开按钮位置
|
|
|
|
|
|
self.lower_open_btn.move(290, 90)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# self.lower_close_btn = CircularButton("关", group)
|
|
|
|
|
|
# self.lower_close_btn.move(233, 233) # 下位料斗的关按钮位置
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
|
|
|
|
|
self.lower_arch_btn = CircularButton("拱", group)
|
|
|
|
|
|
self.lower_arch_btn.move(290, 34) # 下位料斗的破拱按钮位置
|
|
|
|
|
|
|
|
|
|
|
|
return group
|
|
|
|
|
|
|
2025-11-06 10:55:29 +08:00
|
|
|
|
def _update_upper_inner_height(self, total_weight, current_weight: float):
|
|
|
|
|
|
"""根据当前重量占比, 更新upper_inner_label的高度, 实现动态进度的效果"""
|
|
|
|
|
|
# 1、处理边界值(超过总重量按100%,低于0按0%)
|
|
|
|
|
|
clamped_weight = max(0.0, min(current_weight, total_weight))
|
|
|
|
|
|
|
|
|
|
|
|
# 2、计算占比(0~1之间)
|
|
|
|
|
|
weight_ratio = clamped_weight / (total_weight * 1.0)
|
|
|
|
|
|
|
|
|
|
|
|
# 3、根据占比计算实际高度
|
|
|
|
|
|
inner_img_height = 100 # 内部的料斗阴影的高度为100px
|
|
|
|
|
|
target_height = int(weight_ratio * inner_img_height)
|
|
|
|
|
|
|
|
|
|
|
|
# print("target_height: ", target_height)
|
|
|
|
|
|
|
|
|
|
|
|
# 4、设置标签高度(动态变化)
|
|
|
|
|
|
self.upper_inner_label.setFixedHeight(target_height)
|
|
|
|
|
|
|
|
|
|
|
|
# 5、计算标签位置(确保标签底部与父容器底部对齐)
|
2025-11-06 14:05:39 +08:00
|
|
|
|
# container_bottom = self.upper_bg_widget.y() + self.upper_bg_widget.height()
|
|
|
|
|
|
container_bottom = 117 # 容器的高固定为了 117px (背景图片"料斗1"的高)
|
2025-11-06 10:55:29 +08:00
|
|
|
|
label_y = container_bottom - target_height - 8 # 标签顶部y坐标 (减去底部8px)
|
|
|
|
|
|
self.upper_inner_label.move(14, label_y) # x固定,y动态计算
|
2025-11-06 14:05:39 +08:00
|
|
|
|
# print("current_weight",current_weight, "label_y", label_y)
|
2025-11-06 10:55:29 +08:00
|
|
|
|
|
|
|
|
|
|
# 6、强制刷新UI,确保立即显示变化
|
|
|
|
|
|
self.upper_inner_label.update()
|
|
|
|
|
|
|
2025-10-18 18:29:40 +08:00
|
|
|
|
# 上料斗重量设置
|
2025-11-06 15:10:58 +08:00
|
|
|
|
def setUpperHopperWeight(self, weight:int):
|
|
|
|
|
|
# 仅当重量变化时,才更新标签和进度
|
|
|
|
|
|
if weight != self._last_upper_hopper_weight:
|
|
|
|
|
|
# 1、更新上料斗重量标签,显示最新重量
|
|
|
|
|
|
self.upper_weight_label.setText(f"{weight}kg")
|
|
|
|
|
|
|
|
|
|
|
|
# 2、更新上料斗内部进度显示
|
|
|
|
|
|
# 假设上料斗装满之后,总的重量为 5100kg (褚工说设置为 6000kg 11/6)
|
|
|
|
|
|
total_weight = 6000
|
|
|
|
|
|
self._update_upper_inner_height(total_weight, weight)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
2025-11-06 15:10:58 +08:00
|
|
|
|
# 3、设置_last_upper_hopper_weight 为当前重量
|
|
|
|
|
|
self._last_upper_hopper_weight = weight
|
2025-11-06 10:55:29 +08:00
|
|
|
|
|
2025-10-18 18:29:40 +08:00
|
|
|
|
# 上料斗方量设置
|
|
|
|
|
|
def setUpperHopperVolume(self, volume: float):
|
|
|
|
|
|
"""Args:
|
|
|
|
|
|
volume : 传入多少方
|
|
|
|
|
|
"""
|
|
|
|
|
|
self.upper_extra_label.setText(f"{volume}方(预估)")
|
2025-11-04 09:45:14 +08:00
|
|
|
|
|
|
|
|
|
|
# 上料斗夹爪开合角度设置
|
|
|
|
|
|
def setUpperHopperClampAngle(self, angle: float):
|
|
|
|
|
|
"""
|
|
|
|
|
|
Args:
|
|
|
|
|
|
angle: 传入多少角度(单位°)
|
|
|
|
|
|
"""
|
|
|
|
|
|
self.upper_clamp_widget.set_angle(angle)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
|
|
|
|
|
# 下料斗重量设置
|
2025-11-06 15:10:58 +08:00
|
|
|
|
def setLowerHopperWeight(self, weight:int):
|
|
|
|
|
|
# 仅当重量变化时,才更新标签和进度
|
|
|
|
|
|
if weight != self._last_lower_hopper_weight:
|
|
|
|
|
|
# 1、更新下料斗显示标签,显示的重量
|
|
|
|
|
|
self.lower_weight_label.setText(f"{weight}kg")
|
|
|
|
|
|
|
|
|
|
|
|
# 2、更新下料斗的进度显示
|
|
|
|
|
|
# 假设下料斗装满之后 总重量为 5100kg (褚工说设置为 6000kg 11/6)
|
|
|
|
|
|
total_weight = 6000
|
|
|
|
|
|
self._update_lower_inner_height(total_weight, weight)
|
|
|
|
|
|
|
|
|
|
|
|
# 3、设置_last_lower_hopper_weight 为当前重量
|
|
|
|
|
|
self._last_lower_hopper_weight = weight
|
2025-11-06 10:55:29 +08:00
|
|
|
|
|
|
|
|
|
|
def _update_lower_inner_height(self, total_weight, current_weight: float):
|
|
|
|
|
|
# 1、处理边界值
|
|
|
|
|
|
clamped_weight = max(0.0, min(current_weight, total_weight))
|
|
|
|
|
|
|
|
|
|
|
|
# 2、计算占比
|
|
|
|
|
|
weight_ratio = clamped_weight / (total_weight * 1.0)
|
|
|
|
|
|
|
|
|
|
|
|
# 3、根据占比计算当前的实际高度
|
|
|
|
|
|
inner_img_height = 100 # 内部料斗阴影的高度为100px
|
|
|
|
|
|
target_height = int(weight_ratio * inner_img_height)
|
|
|
|
|
|
|
|
|
|
|
|
# 4、设置内部阴影标签的高度
|
|
|
|
|
|
self.lower_inner_label.setFixedHeight(target_height)
|
|
|
|
|
|
|
|
|
|
|
|
# 5、计算标签位置
|
2025-11-06 14:05:39 +08:00
|
|
|
|
# container_bottom = self.lower_bg_widget.y() + self.lower_bg_widget.height()
|
|
|
|
|
|
container_bottom = 117 # 容器的高固定为了 117px (背景图片"料斗1"的高)
|
2025-11-06 10:55:29 +08:00
|
|
|
|
label_y = container_bottom - target_height - 8
|
|
|
|
|
|
self.lower_inner_label.move(14, label_y)
|
2025-11-06 14:05:39 +08:00
|
|
|
|
# print("_update_lower_inner_height", container_bottom)
|
2025-11-06 10:55:29 +08:00
|
|
|
|
|
|
|
|
|
|
# 6、强制刷新UI,确保立即显示变化
|
|
|
|
|
|
self.lower_inner_label.update()
|
|
|
|
|
|
|
2025-11-04 09:45:14 +08:00
|
|
|
|
# 下料斗开合角度设置 (包括 夹爪和标签)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
def setLowerHopperOpeningAngle(self, angle: float):
|
|
|
|
|
|
"""Args:
|
|
|
|
|
|
angle : 传入多少度 (单位°)
|
|
|
|
|
|
"""
|
2025-11-04 09:45:14 +08:00
|
|
|
|
self.lower_extra_label.setText(f"开: {angle}°") # 设置下料斗角度标签
|
|
|
|
|
|
self.lower_clamp_widget.set_angle(angle) # 设置下料斗夹爪开合角度
|
2025-10-18 18:29:40 +08:00
|
|
|
|
|
|
|
|
|
|
# ------------------------------
|
|
|
|
|
|
# 设置上料斗状态(0=绿,1=黄,2=红)
|
|
|
|
|
|
# ------------------------------
|
2025-11-06 10:55:29 +08:00
|
|
|
|
def setUpperHopperStatus(self, status: int):
|
2025-10-18 18:29:40 +08:00
|
|
|
|
"""
|
|
|
|
|
|
设置上料斗状态图片
|
|
|
|
|
|
Args:
|
|
|
|
|
|
status: 状态值(0=绿,1=黄,2=红),非指定值不操作
|
|
|
|
|
|
"""
|
|
|
|
|
|
# 过滤无效状态:不在0/1/2范围内则直接返回,保持当前图片
|
|
|
|
|
|
if status not in [0, 1, 2]:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# 状态-图片路径映射
|
|
|
|
|
|
# 注意:需要替换为实际的图片路径
|
|
|
|
|
|
status_img_map = {
|
2025-11-01 16:13:14 +08:00
|
|
|
|
0: ImagePaths.HOPPER_STATUS_GREEN,
|
|
|
|
|
|
1: ImagePaths.HOPPER_STATUS_YELLOW,
|
|
|
|
|
|
2: ImagePaths.HOPPER_STATUS_RED
|
2025-10-18 18:29:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
img_path = status_img_map[status]
|
|
|
|
|
|
|
|
|
|
|
|
# 加载并缩放图片
|
|
|
|
|
|
status_pixmap = QPixmap(img_path)
|
|
|
|
|
|
if not status_pixmap.isNull():
|
|
|
|
|
|
self.upper_status_label.setPixmap(status_pixmap)
|
|
|
|
|
|
|
|
|
|
|
|
# ------------------------------
|
|
|
|
|
|
# 设置下料斗状态(0=绿,1=黄,2=红)
|
|
|
|
|
|
# ------------------------------
|
2025-11-06 10:55:29 +08:00
|
|
|
|
def setLowerHopperStatus(self, status: int):
|
2025-10-18 18:29:40 +08:00
|
|
|
|
"""
|
|
|
|
|
|
设置下料斗状态图片
|
|
|
|
|
|
Args:
|
|
|
|
|
|
status: 状态值(0=绿,1=黄,2=红),非指定值不操作
|
|
|
|
|
|
"""
|
|
|
|
|
|
if status not in [0, 1, 2]:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# 注意:需要替换为实际的图片路径
|
|
|
|
|
|
status_img_map = {
|
2025-11-01 16:13:14 +08:00
|
|
|
|
0: ImagePaths.HOPPER_STATUS_GREEN,
|
|
|
|
|
|
1: ImagePaths.HOPPER_STATUS_YELLOW,
|
|
|
|
|
|
2: ImagePaths.HOPPER_STATUS_RED
|
2025-10-18 18:29:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
img_path = status_img_map[status]
|
|
|
|
|
|
|
|
|
|
|
|
status_pixmap = QPixmap(img_path)
|
|
|
|
|
|
if not status_pixmap.isNull():
|
|
|
|
|
|
self.lower_status_label.setPixmap(status_pixmap)
|
|
|
|
|
|
|
2025-10-31 18:52:31 +08:00
|
|
|
|
# 隐藏上料斗 (用于上料斗移动)
|
|
|
|
|
|
def hideUpperHopper(self):
|
|
|
|
|
|
self.upper_title_label.hide()
|
|
|
|
|
|
self.upper_bg_widget.hide()
|
|
|
|
|
|
self.upper_clamp_widget.hide()
|
|
|
|
|
|
self.upper_open_btn.hide()
|
|
|
|
|
|
self.upper_arch_btn.hide()
|
|
|
|
|
|
|
|
|
|
|
|
# 显示上料斗 (用于上料斗移动完成后恢复显示)
|
|
|
|
|
|
def showUpperHopper(self):
|
|
|
|
|
|
self.upper_title_label.setHidden(False)
|
|
|
|
|
|
self.upper_bg_widget.setHidden(False)
|
|
|
|
|
|
self.upper_clamp_widget.setHidden(False)
|
|
|
|
|
|
self.upper_open_btn.setHidden(False)
|
|
|
|
|
|
self.upper_arch_btn.setHidden(False)
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-10-18 18:29:40 +08:00
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
|
|
window = HopperWidget()
|
|
|
|
|
|
window.setLowerHopperWeight(2000)
|
|
|
|
|
|
window.setUpperHopperVolume(3.0)
|
|
|
|
|
|
window.setLowerHopperOpeningAngle(45)
|
2025-11-06 10:55:29 +08:00
|
|
|
|
window.setUpperHopperStatus(2)
|
|
|
|
|
|
window.setLowerHopperStatus(1)
|
2025-10-18 18:29:40 +08:00
|
|
|
|
window.show()
|
|
|
|
|
|
sys.exit(app.exec())
|