#!/usr/bin/env python # -*- coding: utf-8 -*- ''' # @Time : 2025/11/10 11:29 # @Author : reenrr # @Description : 重量显示界面,显示上料斗重量、下料斗重量 ''' from PySide6.QtWidgets import ( QApplication, QDialog, QVBoxLayout, QHBoxLayout, QGridLayout, QLabel, QWidget, QPushButton, ) from PySide6.QtGui import QPixmap, QFont, QPainter, QIcon from PySide6.QtCore import Qt, QEvent, QSize, QTimer, Slot from PySide6.QtNetwork import QTcpSocket, QAbstractSocket import sys import json from datetime import datetime class WeightDetailsDialog(QDialog): """ 上料斗、下料斗重量显示界面 """ def __init__(self, parent=None, title="上料斗重量" ): super().__init__(parent) self.setAttribute(Qt.WA_TranslucentBackground) self.digit_labels = [] #用于存储数字标签的列表 self.default_icon_path = "选择_未实时.png" # 未连接图标 self.connected_icon_path = "选择_实时.png" # 已连接图标 self.check_label = None # 状态图标标签 self.is_running = False # 定时器是否运行 self.statusWidgets = [] # 状态显示控件列表 # 存储当前重量值(用于处理空值/异常值) self.current_weight = 0.0 self._init_ui(title) # ----------------------- # 界面初始化函数 # ----------------------- def _init_ui(self, title): self.setWindowFlags(Qt.FramelessWindowHint) self._load_background() main_layout = QVBoxLayout(self) main_layout.setContentsMargins(32, 20, 32, 50) main_layout.setSpacing(0) # 1. 顶部区域(标题 + 关闭按钮) self._add_top_area(main_layout, title) # 2. 状态显示+重量框 self._add_state_weight_area(main_layout) def _load_background(self): self.bg_pixmap = QPixmap("重量背景.png") # 修改为派单任务背景图 if self.bg_pixmap.isNull(): print("错误:重量背景.png 加载失败,请检查路径!") self.setFixedSize(800, 500) else: self.setFixedSize(self.bg_pixmap.size()) def _add_top_area(self, parent_layout, title): top_layout = QHBoxLayout() top_layout.setContentsMargins(0, 0, 0, 36) top_layout.addStretch() title_label = QLabel(title) font = QFont() font.setPixelSize(24) font.setLetterSpacing(QFont.AbsoluteSpacing, 2) font.setBold(True) title_label.setFont(font) title_label.setStyleSheet("color: #13fffc; font-weight: Bold;") title_label.setAlignment(Qt.AlignCenter) top_layout.addWidget(title_label, alignment=Qt.AlignTop) # 关闭按钮 top_layout.addStretch() parent_layout.addLayout(top_layout) def _add_state_weight_area(self, parent_layout): grid_layout = QGridLayout() grid_layout.setSpacing(12) weight_widget = self._create_info_weight() grid_layout.addWidget(weight_widget) parent_layout.addLayout(grid_layout) def _create_info_weight(self): # 1、创建最外层水平布局(容纳所有元素) weight_layout = QHBoxLayout() weight_layout.setContentsMargins(0, 0, 0, 0) weight_layout.setSpacing(0) # 2、创建确认图标 self.check_label = QLabel() self._update_status_icon1(False) self._update_status_icon2(False) weight_layout.addWidget(self.check_label) weight_layout.setSpacing(50) # 3、创建“6个数字单元格” digit_font = QFont() digit_font.setPixelSize(70) digit_font.setLetterSpacing(QFont.AbsoluteSpacing, 2) digit_font.setBold(False) digit_pixmap = QPixmap("数字.png") digit_size = digit_pixmap.size() for i in range(6): # 数字标签 digit_label = QLabel("") digit_label.setFixedSize(digit_size) digit_label.setFont(digit_font) digit_label.setAlignment(Qt.AlignCenter) digit_label.setStyleSheet("color: white") # 若图片存在,设置背景图片 if not digit_pixmap.isNull(): digit_label.setStyleSheet(""" QLabel { color: white; background-image: url(数字.png); background-repeat: no-repeat; background-position: center; } """) weight_layout.addWidget(digit_label) self.digit_labels.append(digit_label) if i < 5: weight_layout.addSpacing(5) # 4、创建“kg”单位单元格 unit_label = QLabel("kg") unit_label.setFixedSize(digit_size) unit_label.setFont(digit_font) unit_label.setAlignment(Qt.AlignCenter) if not digit_pixmap.isNull(): unit_label.setStyleSheet(""" QLabel { color: white; background-image: url(数字.png); background-repeat: no-repeat; background-position: center; } """) weight_layout.addSpacing(5) weight_layout.addWidget(unit_label) # 5、将主布局设置到父控件 weight_widget = QWidget() weight_widget.setLayout(weight_layout) weight_widget.setObjectName("infoWeight") return weight_widget def eventFilter(self, obj, event): """ 实现事件过滤器,动态修改右侧值颜色 """ # 只处理父控件(infoCell)的事件 if obj.objectName() == "infoCell": # 鼠标进入父控件 → 改#13f0f3 if event.type() == QEvent.Enter: if hasattr(obj, "value"): # 确保存在value控件 obj.value.setStyleSheet("background: none; color: #13f0f3;") # 鼠标离开父控件 → 恢复默认色 elif event.type() == QEvent.Leave: if hasattr(obj, "value"): obj.value.setStyleSheet("background: none; color: #9fbfd4;") return super().eventFilter(obj, event) def paintEvent(self, event): if not self.bg_pixmap.isNull(): painter = QPainter(self) painter.drawPixmap(self.rect(), self.bg_pixmap) super().paintEvent(event) def update_weight(self, weight_data): """根据TCP获取的数据更新重量显示""" # 更新6个数字标签(补零为6位,超过6位取后6位) # 处理空值/异常值(客户端传递的 "" 或 "error") if weight_data == "" or weight_data == "error" or weight_data is None: weight_str = "000000" self.current_weight = 0 else: try: # 支持浮点数(如 648.06 → 保留2位小数后转为整数显示,避免丢失精度) weight_int = int(float(weight_data)) self.current_weight = weight_int weight_str = f"{weight_int:06d}"[-6:] # 超过6位取后6位 except (ValueError, TypeError): weight_str = "000000" self.current_weight = 0 # 更新6个数字标签 for i in range(min(len(self.digit_labels), 6)): self.digit_labels[i].setText(weight_str[i] if i < len(weight_str) else "0") def _update_status_icon1(self, is_connected): """根据连接状态切换图标""" if not self.check_label: return icon_path = self.connected_icon_path if is_connected else self.default_icon_path pixmap = QPixmap(icon_path) if not pixmap.isNull(): self.check_label.setPixmap(pixmap.scaled( pixmap.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) else: print(f"错误:{icon_path} 加载失败,请检查路径!") def _update_status_icon2(self, is_error): """根据是否有错误信息,切换图标""" if not self.check_label: return icon_path = self.default_icon_path if is_error else self.connected_icon_path pixmap = QPixmap(icon_path) if not pixmap.isNull(): self.check_label.setPixmap(pixmap.scaled( pixmap.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) else: print(f"错误:{icon_path} 加载失败,请检查路径!") # -------------------- # 清空界面信息的通用方法 # -------------------- def _clear_ui_info(self): """清空管片ID和网格信息""" # 修复:避免访问未定义的 self.id_value_label if hasattr(self, 'id_value_label') and self.id_value_label: self.id_value_label.setText("") for widget in self.statusWidgets: if 'valueLabel' in widget and widget['valueLabel']: widget['valueLabel'].setText("") # 清空重量显示 for label in self.digit_labels: label.setText("0") print("ℹ️ 界面信息已清空") # 测试代码 if __name__ == "__main__": app = QApplication(sys.argv) dialog = WeightDetailsDialog() dialog.show() sys.exit(app.exec())