Files
Feeding_control_system/view/widgets/status_monitor_widget.py

242 lines
9.3 KiB
Python
Raw Normal View History

2025-10-18 18:29:40 +08:00
from PySide6.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QMessageBox, QLabel, QGridLayout, QDialog
from PySide6.QtGui import QPainter, QColor, QBrush, QFont, QPixmap
from PySide6.QtCore import Qt
import sys
import datetime
2025-10-31 18:52:31 +08:00
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 DeviceStatusPopup(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("设备状态")
self.setFixedSize(898, 354) # 固定总尺寸为898x354
# 通用字体设置:微软雅黑 18px
font = QFont()
font.setFamily("Microsoft YaHei")
font.setPointSize(18)
# 初始化UI组件
self.ip_label = QLabel("ip地址")
self.ip_value = QLabel()
self.status_label = QLabel("连接状态")
self.status_img = QLabel()
self.status_img.setFixedSize(80, 41) # 状态图片尺寸
self.time_label = QLabel("更新时间")
self.time_value = QLabel()
self.algorithm_label = QLabel("算法结果")
self.algorithm_value = QLabel()
# 右侧大图片369x185
self.right_image = QLabel()
# self.right_image.setFixedSize(369, 185)
self.right_image.setFixedSize(520, 320)
# 临时设置占位图(实际使用时替换为你的图片路径)
# placeholder = QPixmap(520, 340)
# placeholder.fill(QColor(229, 229, 229)) # 灰色占位
# self.right_image.setPixmap(placeholder)
self.right_image.setText("图片未加载")
self.right_image.setStyleSheet("background-color: rgb(229,229,229)")
self.right_image.setAlignment(Qt.AlignCenter) # 图片居中显示
# 左侧栏字体设置:微软雅黑 18px
left_font = QFont("Microsoft YaHei", 18)
# 右侧栏字体设置:微软雅黑 15px
right_font = QFont("Microsoft YaHei", 15)
# 设置左侧文本标签的字体和左对齐
for label in [self.ip_label, self.status_label,
self.time_label, self.algorithm_label]:
label.setFont(left_font)
label.setAlignment(Qt.AlignLeft) # 左对齐
# 设置右侧文本标签的字体和左对齐
for label in [self.ip_value, self.time_value, self.algorithm_value]:
label.setFont(right_font)
label.setAlignment(Qt.AlignLeft) # 左对齐
# 三列布局:左侧标签列 + 中间内容列 + 右侧图片列
layout = QGridLayout()
# 设置布局边距和间距(避免内容贴边)
layout.setContentsMargins(10, 10, 10, 10) # 上下左右边距
layout.setSpacing(15) # 控件间距
# 第一列:标签(左对齐)
layout.addWidget(self.ip_label, 0, 0, alignment=Qt.AlignLeft | Qt.AlignVCenter)
layout.addWidget(self.status_label, 1, 0, alignment=Qt.AlignLeft | Qt.AlignVCenter)
layout.addWidget(self.time_label, 2, 0, alignment=Qt.AlignLeft | Qt.AlignVCenter)
layout.addWidget(self.algorithm_label, 3, 0, alignment=Qt.AlignLeft | Qt.AlignVCenter)
# 第二列:内容(左对齐)
layout.addWidget(self.ip_value, 0, 1, alignment=Qt.AlignLeft | Qt.AlignVCenter)
layout.addWidget(self.status_img, 1, 1, alignment=Qt.AlignLeft | Qt.AlignVCenter)
layout.addWidget(self.time_value, 2, 1, alignment=Qt.AlignLeft | Qt.AlignVCenter)
layout.addWidget(self.algorithm_value, 3, 1, alignment=Qt.AlignLeft | Qt.AlignVCenter)
# 第三列右侧大图片跨4行垂直居中
layout.addWidget(self.right_image, 0, 2, 4, 1, alignment=Qt.AlignCenter)
# 列宽分配总宽度898 = 左列 + 中列 + 右列(369) + 边距(40) + 间距(30)
# 计算可用宽度898 - 10*2(边距) - 15*2(列间距) - 520(右列) = 328
layout.setColumnStretch(0, 1) # 左列占1份
layout.setColumnStretch(1, 2) # 中列占2份总3份分配328宽度
self.setLayout(layout)
# 初始状态设置
self.update_connection_status("在线")
self.update_algorithm_result("ok")
self.update_ip_address("192.168.1.5")
def update_connection_status(self, status: str):
"""更新连接状态,切换显示图片"""
2025-11-01 16:13:14 +08:00
img_path = ImagePaths.ONLINE if status == "在线" else ImagePaths.OFFLINE
2025-10-18 18:29:40 +08:00
pixmap = QPixmap(img_path)
self.status_img.setPixmap(pixmap.scaled(
self.status_img.width(),
self.status_img.height(),
Qt.KeepAspectRatio,
Qt.SmoothTransformation
))
self._update_time()
def _update_time(self):
"""刷新当前时间"""
now = datetime.datetime.now()
self.time_value.setText(now.strftime("%Y-%m-%d %H:%M:%S"))
def update_ip_address(self, ip: str):
"""更新IP地址"""
self.ip_value.setText(ip)
def update_algorithm_result(self, result: str):
"""更新算法结果"""
self.algorithm_value.setText(result)
def update_right_image(self, img_path: str):
"""更新右侧大图片的接口"""
pixmap = QPixmap(img_path)
self.right_image.setPixmap(pixmap.scaled(
self.right_image.width(),
self.right_image.height(),
Qt.KeepAspectRatio,
Qt.SmoothTransformation
))
class CircularPushButton(QPushButton):
"""圆形按钮组件,点击触发弹窗"""
def __init__(self, text, parent=None):
super().__init__(text, parent)
self.setFixedSize(66, 66) # 固定尺寸60x60
self.setFont(QFont("Microsoft YaHei", 9)) # 字体适配尺寸
# 状态颜色定义
self.color_map = {
0: QColor(109, 218, 99), # 正常-绿色
1: QColor(222, 182, 61), # 警告-黄色
2: QColor(241, 63, 61) # 异常-红色
}
self.current_status = 0 # 默认正常状态
def set_status(self, status: int):
"""设置状态0-正常1-警告2-异常"""
if status in self.color_map:
self.current_status = status
self.update() # 触发重绘
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing) # 抗锯齿
# 绘制圆形背景
brush = QBrush(self.color_map[self.current_status])
painter.setBrush(brush)
painter.setPen(Qt.NoPen)
painter.drawEllipse(0, 0, self.width(), self.height())
# 绘制文字
painter.setPen(Qt.black)
painter.drawText(self.rect(), Qt.AlignCenter, self.text())
class StatusMonitorWidget(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.setWindowTitle("设备状态监控面板")
# self.resize(600, 120) # 窗口大小适配按钮尺寸
self.setFixedSize(720, 100)
layout = QHBoxLayout(self)
layout.setSpacing(15) # 组件间距
layout.setContentsMargins(20, 20, 20, 20) # 窗口边距
# 初始化所有圆形按钮
self.buttons = [
CircularPushButton("RFID对比"),
CircularPushButton("盖板对齐"),
CircularPushButton("溢料状态"),
CircularPushButton("下料度"),
CircularPushButton("IOT平台"),
CircularPushButton("任务平台"),
CircularPushButton("搅拌楼"),
CircularPushButton("LED"),
CircularPushButton("控制设备")
]
# 为每个按钮连接点击弹窗事件
for idx, btn in enumerate(self.buttons):
btn.clicked.connect(lambda checked, btn_idx=idx: self.show_popup(btn_idx))
# 将按钮添加到布局
for btn in self.buttons:
layout.addWidget(btn)
def show_popup(self, btn_idx):
"""点击按钮后弹出提示窗口"""
btn_text = self.buttons[btn_idx].text()
status_map = {0: "正常", 1: "警告", 2: "异常"}
status = status_map[self.buttons[btn_idx].current_status]
# QMessageBox.information(
# self,
# f"{btn_text} 详情",
# f"设备:{btn_text}\n状态{status}\n"
# )
statusWin = DeviceStatusPopup(self)
# 此处 可以更新设备的状态,如 设备ip、算法结果等
# 需要连接检测相关代码
statusWin.exec()
def setButtonStatus(self, button_name: str, status: int):
"""
根据按钮名称设置状态
Args:
button_name: 按钮显示的文本"RFID对比"
status: 状态值0-正常1-警告2-异常
"""
# 遍历按钮列表,匹配名称
for btn in self.buttons:
if btn.text() == button_name:
btn.set_status(status) # 调用按钮的set_status方法
return # 找到后退出循环
# 未找到对应按钮,打印提示
print(f"警告:未找到名为「{button_name}」的按钮")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = StatusMonitorWidget()
window.setButtonStatus("溢料状态", 1)
window.setButtonStatus("LED", 2)
window.show()
sys.exit(app.exec())