241 lines
9.3 KiB
Python
241 lines
9.3 KiB
Python
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
|
||
|
||
import resources.resource_rc
|
||
|
||
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):
|
||
"""更新连接状态,切换显示图片"""
|
||
img_path = ":/icons/images/在线.png" if status == "在线" else ":/icons/images/离线.png"
|
||
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()) |