407 lines
18 KiB
Python
407 lines
18 KiB
Python
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
|
||
|
||
import resources.resource_rc
|
||
|
||
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 # 初始为不破拱状态
|
||
|
||
# 料斗控制界面的固定大小为 332x482,
|
||
# 需要根据具体的料斗的图片来调整
|
||
self.setFixedSize(356, 496)
|
||
|
||
# 创建上位和下位料斗
|
||
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()
|
||
|
||
# 上位的 料斗控件的固定尺寸 !!!!
|
||
# 注意: 这里需要根据具体的料斗图片来修改
|
||
group.setFixedSize(332, 202)
|
||
# group.setStyleSheet("background-color: green")
|
||
|
||
layout = QVBoxLayout(group)
|
||
layout.setSpacing(0)
|
||
layout.setContentsMargins(0, 0, 0, 0)
|
||
|
||
# 标题标签(上位)
|
||
self.upper_title_label = QLabel("上位料斗")
|
||
self.upper_title_label.setFixedSize(79, 17)
|
||
self.upper_title_label.setAlignment(Qt.AlignCenter)
|
||
self.upper_title_label.setStyleSheet("color: #2fd3f2; font-size: 14px; font-weight: bold;")
|
||
layout.addWidget(self.upper_title_label, alignment=Qt.AlignCenter)
|
||
|
||
# 加载外框图片
|
||
outer_img = ":/icons/images/上位料斗1.png"
|
||
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)
|
||
self.upper_bg_widget.setStyleSheet(f"background-image: url({outer_img}); background-repeat: no-repeat; background-position: center;")
|
||
layout.addWidget(self.upper_bg_widget, alignment=Qt.AlignCenter)
|
||
|
||
# 内框图片(上位)
|
||
inner_img = ":/icons/images/上位料斗2.png"
|
||
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)
|
||
self.upper_inner_label.setFixedSize(inner_pixmap.width(), inner_pixmap.height())
|
||
self.upper_inner_label.move(14, 9)
|
||
|
||
# 状态图片(上位,绿色)
|
||
status_img = ":/icons/images/料斗状态绿.png"
|
||
status_pixmap = QPixmap(status_img)
|
||
if not status_pixmap.isNull():
|
||
status_pixmap = status_pixmap.scaled(22, 22, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
||
self.upper_status_label = QLabel(self.upper_bg_widget)
|
||
self.upper_status_label.setPixmap(status_pixmap)
|
||
self.upper_status_label.move(32, 18)
|
||
self.upper_status_label.setScaledContents(False)
|
||
self.upper_status_label.setStyleSheet("background: none;")
|
||
|
||
# 破拱图片(上位)
|
||
arch_img = ":/icons/images/破拱.png"
|
||
arch_pixmap = QPixmap(arch_img)
|
||
if not arch_pixmap.isNull():
|
||
arch_pixmap = arch_pixmap.scaled(24, 21, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
||
self.upper_arch_label = QLabel(self.upper_bg_widget)
|
||
self.upper_arch_label.setPixmap(arch_pixmap)
|
||
self.upper_arch_label.move(outer_width - 56, 18)
|
||
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)
|
||
self.upper_weight_label.setStyleSheet("background: none; background-color: #262c38; color: #79c053; font-size: 14px; font-weight: bold;")
|
||
self.upper_weight_label.setFixedSize(93, 22)
|
||
self.upper_weight_label.move(outer_width//2 - 46, outer_height//2 - 30)
|
||
|
||
# 额外文字(上位)
|
||
self.upper_extra_label = QLabel("2.0方(预估)", self.upper_bg_widget)
|
||
self.upper_extra_label.setAlignment(Qt.AlignCenter)
|
||
self.upper_extra_label.setStyleSheet("background: none; background-color: #262c38; color: #79c053; font-size: 14px; font-weight: bold;")
|
||
self.upper_extra_label.setFixedSize(93, 22)
|
||
self.upper_extra_label.move(outer_width//2 - 46, outer_height//2)
|
||
|
||
# 料斗夹具图片(上位)
|
||
# clamp_img = ":/icons/images/料斗夹具.png"
|
||
# clamp_pixmap = QPixmap(clamp_img)
|
||
# if not clamp_pixmap.isNull():
|
||
# self.upper_clamp_label = QLabel()
|
||
# self.upper_clamp_label.setPixmap(clamp_pixmap)
|
||
# self.upper_clamp_label.setFixedSize(clamp_pixmap.width(), clamp_pixmap.height())
|
||
# layout.addWidget(self.upper_clamp_label, alignment=Qt.AlignCenter)
|
||
|
||
# 料斗夹具图片(上位,固定152x60尺寸,图片自适应缩放)
|
||
# 注意:目前由于给出的 料斗夹具图片尺寸大了,只能够先缩放,后期图片对了,可以用上面的
|
||
clamp_img = ":/icons/images/料斗夹具.png"
|
||
clamp_pixmap = QPixmap(clamp_img)
|
||
if not clamp_pixmap.isNull():
|
||
self.upper_clamp_label = QLabel()
|
||
# 1. 固定QLabel尺寸为152x60
|
||
self.upper_clamp_label.setFixedSize(152, 60)
|
||
# 2. 图片缩放到152x60(保持比例,平滑缩放)
|
||
scaled_pixmap = clamp_pixmap.scaled(
|
||
152, 60,
|
||
Qt.KeepAspectRatio, # 保持图片原始比例,避免变形
|
||
Qt.SmoothTransformation # 平滑缩放,提升显示效果
|
||
)
|
||
self.upper_clamp_label.setPixmap(scaled_pixmap)
|
||
# 3. 确保图片在QLabel中居中显示
|
||
self.upper_clamp_label.setAlignment(Qt.AlignCenter)
|
||
layout.addWidget(self.upper_clamp_label, alignment=Qt.AlignCenter)
|
||
|
||
# 按钮(上位)
|
||
self.upper_open_btn = CircularButton("开", group)
|
||
self.upper_open_btn.move(60, 153) # 上位料斗的开按钮位置
|
||
|
||
self.upper_close_btn = CircularButton("关", group)
|
||
self.upper_close_btn.move(233, 153) # 上位料斗的关按钮位置
|
||
|
||
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()
|
||
|
||
# 下位的 料斗控件的固定尺寸 !!!!
|
||
# 注意: 这里需要根据具体的料斗图片来修改
|
||
group.setFixedSize(332, 280)
|
||
# group.setStyleSheet("background-color: black")
|
||
|
||
layout = QVBoxLayout(group)
|
||
layout.setSpacing(0)
|
||
layout.setContentsMargins(0, 0, 0, 0)
|
||
|
||
# 标题标签(下位)
|
||
self.lower_title_label = QLabel("低位料斗")
|
||
self.lower_title_label.setFixedSize(79, 17)
|
||
self.lower_title_label.setAlignment(Qt.AlignCenter)
|
||
self.lower_title_label.setStyleSheet("color: #2fd3f2; font-size: 14px; font-weight: bold;")
|
||
layout.addWidget(self.lower_title_label, alignment=Qt.AlignCenter)
|
||
|
||
# 加载外框图片
|
||
outer_img = ":/icons/images/下位料斗1.png"
|
||
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)
|
||
|
||
# 内框图片(下位)
|
||
inner_img = ":/icons/images/下位料斗2.png"
|
||
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())
|
||
self.lower_inner_label.move(14, 9)
|
||
|
||
# 状态图片(下位,红色)
|
||
status_img = ":/icons/images/料斗状态绿.png"
|
||
status_pixmap = QPixmap(status_img)
|
||
if not status_pixmap.isNull():
|
||
status_pixmap = status_pixmap.scaled(22, 22, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
||
self.lower_status_label = QLabel(self.lower_bg_widget)
|
||
self.lower_status_label.setPixmap(status_pixmap)
|
||
self.lower_status_label.move(32, 18)
|
||
self.lower_status_label.setScaledContents(False)
|
||
self.lower_status_label.setStyleSheet("background: none;")
|
||
|
||
# 破拱图片(下位)
|
||
arch_img = ":/icons/images/破拱.png"
|
||
arch_pixmap = QPixmap(arch_img)
|
||
if not arch_pixmap.isNull():
|
||
arch_pixmap = arch_pixmap.scaled(24, 21, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
||
self.lower_arch_label = QLabel(self.lower_bg_widget)
|
||
self.lower_arch_label.setPixmap(arch_pixmap)
|
||
self.lower_arch_label.move(outer_width - 56, 18)
|
||
self.lower_arch_label.setStyleSheet("background: none;")
|
||
self.lower_arch_label.setHidden(True) # 初始,不破拱状态,隐藏
|
||
|
||
# 重量文字(下位)
|
||
self.lower_weight_label = QLabel("5000kg", self.lower_bg_widget)
|
||
self.lower_weight_label.setStyleSheet("background: none; background-color: #262c38; color: #79c053; font-size: 14px;font-weight: bold;")
|
||
self.lower_weight_label.setAlignment(Qt.AlignCenter)
|
||
self.lower_weight_label.setFixedSize(93, 22)
|
||
self.lower_weight_label.move(outer_width//2 - 46, outer_height//2 - 46)
|
||
|
||
# 额外文字(下位)
|
||
self.lower_extra_label = QLabel("开: 25°", self.lower_bg_widget)
|
||
self.lower_extra_label.setAlignment(Qt.AlignCenter)
|
||
self.lower_extra_label.setStyleSheet("background: none; background-color: #262c38; color: #79c053; font-size: 14px;font-weight: bold;")
|
||
self.lower_extra_label.setFixedSize(93, 22)
|
||
self.lower_extra_label.move(outer_width//2 - 46, outer_height//2 - 20)
|
||
|
||
# 料斗夹具图片(下位)
|
||
# clamp_img = ":/icons/images/料斗夹具.png"
|
||
# clamp_pixmap = QPixmap(clamp_img)
|
||
# if not clamp_pixmap.isNull():
|
||
# self.lower_clamp_label = QLabel()
|
||
# self.lower_clamp_label.setPixmap(clamp_pixmap)
|
||
# self.lower_clamp_label.setFixedSize(clamp_pixmap.width(), clamp_pixmap.height())
|
||
# layout.addWidget(self.lower_clamp_label, alignment=Qt.AlignCenter)
|
||
|
||
# 目前由于给出的 料斗夹具图片尺寸大了,只能够先缩放,后期图片对了,可以用上面的
|
||
clamp_img = ":/icons/images/料斗夹具.png"
|
||
clamp_pixmap = QPixmap(clamp_img)
|
||
if not clamp_pixmap.isNull():
|
||
self.lower_clamp_label = QLabel()
|
||
# 1. 固定QLabel尺寸为152x60
|
||
self.lower_clamp_label.setFixedSize(152, 60)
|
||
# 2. 图片缩放到152x60(保持比例,平滑缩放)
|
||
scaled_pixmap = clamp_pixmap.scaled(
|
||
152, 60,
|
||
Qt.KeepAspectRatio, # 保持图片原始比例,避免变形
|
||
Qt.SmoothTransformation # 平滑缩放,提升显示效果
|
||
)
|
||
self.lower_clamp_label.setPixmap(scaled_pixmap)
|
||
# 3. 确保图片在QLabel中居中显示
|
||
self.lower_clamp_label.setAlignment(Qt.AlignCenter)
|
||
layout.addWidget(self.lower_clamp_label, alignment=Qt.AlignCenter)
|
||
|
||
# 按钮(下位)
|
||
self.lower_open_btn = CircularButton("开", group)
|
||
self.lower_open_btn.move(60, 233) # 下位料斗的开按钮位置
|
||
|
||
self.lower_close_btn = CircularButton("关", group)
|
||
self.lower_close_btn.move(233, 233) # 下位料斗的关按钮位置
|
||
|
||
self.lower_arch_btn = CircularButton("拱", group)
|
||
self.lower_arch_btn.move(290, 34) # 下位料斗的破拱按钮位置
|
||
|
||
return group
|
||
|
||
# 上料斗重量设置
|
||
def setUpperHopperWeight(self, weight:float):
|
||
self.upper_weight_label.setText(f"{weight}kg")
|
||
|
||
# 上料斗方量设置
|
||
def setUpperHopperVolume(self, volume: float):
|
||
"""Args:
|
||
volume : 传入多少方
|
||
"""
|
||
self.upper_extra_label.setText(f"{volume}方(预估)")
|
||
|
||
# 下料斗重量设置
|
||
def setLowerHopperWeight(self, weight:float):
|
||
self.lower_weight_label.setText(f"{weight}kg")
|
||
|
||
# 下料斗开合角度设置
|
||
def setLowerHopperOpeningAngle(self, angle: float):
|
||
"""Args:
|
||
angle : 传入多少度 (单位°)
|
||
"""
|
||
self.lower_extra_label.setText(f"开: {angle}°")
|
||
|
||
# ------------------------------
|
||
# 设置上料斗状态(0=绿,1=黄,2=红)
|
||
# ------------------------------
|
||
def setUpperArchStatus(self, status: int):
|
||
"""
|
||
设置上料斗状态图片
|
||
Args:
|
||
status: 状态值(0=绿,1=黄,2=红),非指定值不操作
|
||
"""
|
||
# 过滤无效状态:不在0/1/2范围内则直接返回,保持当前图片
|
||
if status not in [0, 1, 2]:
|
||
return
|
||
|
||
# 状态-图片路径映射
|
||
# 注意:需要替换为实际的图片路径
|
||
status_img_map = {
|
||
0: ":/icons/images/料斗状态绿.png",
|
||
1: ":/icons/images/料斗状态黄.png",
|
||
2: ":/icons/images/料斗状态红.png"
|
||
}
|
||
img_path = status_img_map[status]
|
||
|
||
# 加载并缩放图片
|
||
status_pixmap = QPixmap(img_path)
|
||
if not status_pixmap.isNull():
|
||
status_pixmap = status_pixmap.scaled(
|
||
22, 22,
|
||
Qt.KeepAspectRatio,
|
||
Qt.SmoothTransformation
|
||
)
|
||
self.upper_status_label.setPixmap(status_pixmap)
|
||
|
||
# ------------------------------
|
||
# 设置下料斗状态(0=绿,1=黄,2=红)
|
||
# ------------------------------
|
||
def setLowerArchStatus(self, status: int):
|
||
"""
|
||
设置下料斗状态图片
|
||
Args:
|
||
status: 状态值(0=绿,1=黄,2=红),非指定值不操作
|
||
"""
|
||
if status not in [0, 1, 2]:
|
||
return
|
||
|
||
# 注意:需要替换为实际的图片路径
|
||
status_img_map = {
|
||
0: ":/icons/images/料斗状态绿.png",
|
||
1: ":/icons/images/料斗状态黄.png",
|
||
2: ":/icons/images/料斗状态红.png"
|
||
}
|
||
img_path = status_img_map[status]
|
||
|
||
status_pixmap = QPixmap(img_path)
|
||
if not status_pixmap.isNull():
|
||
status_pixmap = status_pixmap.scaled(
|
||
22, 22,
|
||
Qt.KeepAspectRatio,
|
||
Qt.SmoothTransformation
|
||
)
|
||
self.lower_status_label.setPixmap(status_pixmap)
|
||
|
||
if __name__ == "__main__":
|
||
app = QApplication(sys.argv)
|
||
window = HopperWidget()
|
||
window.setLowerHopperWeight(2000)
|
||
window.setUpperHopperVolume(3.0)
|
||
window.setLowerHopperOpeningAngle(45)
|
||
window.setUpperArchStatus(2)
|
||
window.setLowerArchStatus(1)
|
||
window.show()
|
||
sys.exit(app.exec()) |