V2.0
This commit is contained in:
268
main.py
268
main.py
@ -1,34 +1,43 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
# @Time : 2025/9/10 11:29
|
||||||
|
# @Author : reenrr
|
||||||
|
# @File : test.py
|
||||||
|
'''
|
||||||
import sys
|
import sys
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QApplication, QWidget, QVBoxLayout, QHBoxLayout,
|
QApplication, QWidget, QVBoxLayout, QHBoxLayout,
|
||||||
QLabel, QFrame, QSizePolicy, QPushButton
|
QLabel, QFrame, QSizePolicy, QPushButton
|
||||||
)
|
)
|
||||||
from PySide6.QtCore import Qt, QTimer
|
from PySide6.QtCore import Qt, QTimer, QPoint, QSize
|
||||||
from PySide6.QtGui import QFont
|
from PySide6.QtGui import QFont, QPainter, QColor, QPen, QIcon
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
class StatusMonitor(QWidget):
|
class StatusMonitor(QWidget):
|
||||||
"""
|
"""
|
||||||
中交三航精准布料浇筑要料系统 - 主界面类
|
中交三航精准布料浇筑要料系统 - 主界面类(深色主题)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
"""构造函数:初始化主界面的UI布局、控件和定时器"""
|
"""构造函数:初始化主界面的UI布局、控件和定时器"""
|
||||||
super().__init__(parent=parent)
|
super().__init__(parent=parent)
|
||||||
self.is_running = False # 系统运行状态标记
|
self.is_running = False # 系统运行状态标记
|
||||||
|
self.current_datetime = self.get_current_time() # 当前日期时间
|
||||||
|
|
||||||
# 窗口基础设置
|
# 窗口基础设置
|
||||||
self.setWindowTitle("中交三航精准布料浇筑要料系统")
|
self.setWindowTitle("中交三航精准布料浇筑要料系统")
|
||||||
self.setGeometry(100, 100, 800, 500) # 设置窗口位置和大小
|
self.setGeometry(100, 100, 800, 500) # 设置窗口位置和大小
|
||||||
|
self.setStyleSheet("background-color: #121212;") # 窗口背景设为深黑色
|
||||||
|
|
||||||
# 初始化主布局(垂直布局)
|
# 初始化主布局(垂直布局)
|
||||||
self.mainLayout = QVBoxLayout(self)
|
self.mainLayout = QVBoxLayout(self)
|
||||||
self.mainLayout.setContentsMargins(10, 10, 10, 10) # 设置布局的内边距
|
self.mainLayout.setContentsMargins(10, 40, 10, 10) # 上边距留空用于显示日期
|
||||||
self.mainLayout.setSpacing(10) # 相邻控件的间距
|
self.mainLayout.setSpacing(10) # 相邻控件的间距
|
||||||
|
|
||||||
# 初始化界面组件
|
# 初始化界面组件
|
||||||
self._init_title_label()
|
self._init_title_label()
|
||||||
self._init_time_label()
|
|
||||||
self._init_status_container()
|
self._init_status_container()
|
||||||
self._init_timers()
|
self._init_timers()
|
||||||
|
|
||||||
@ -37,45 +46,22 @@ class StatusMonitor(QWidget):
|
|||||||
titleLabel = QLabel("中交三航精准布料浇筑要料系统")
|
titleLabel = QLabel("中交三航精准布料浇筑要料系统")
|
||||||
titleLabel.setStyleSheet("""
|
titleLabel.setStyleSheet("""
|
||||||
QLabel {
|
QLabel {
|
||||||
background-color: #66BB6A;
|
color: #00FF9D;
|
||||||
color: white;
|
font-size: 20px;
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 15px;
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 2px solid #E8F5E9;
|
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
titleLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
titleLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
titleLabel.setFont(QFont("Microsoft YaHei", 24, QFont.Bold))
|
titleLabel.setFont(QFont("Microsoft YaHei", 24, QFont.Bold))
|
||||||
self.mainLayout.addWidget(titleLabel)
|
self.mainLayout.addWidget(titleLabel)
|
||||||
|
|
||||||
def _init_time_label(self):
|
|
||||||
"""初始化实时时间显示标签"""
|
|
||||||
self.timeLabel = QLabel(self.get_current_time())
|
|
||||||
self.timeLabel.setStyleSheet("""
|
|
||||||
background-color: #E8F5E9;
|
|
||||||
color: #2E7D32;
|
|
||||||
font-size: 16px;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border-radius: 6px;
|
|
||||||
border: 1px solid #C8E6C9;
|
|
||||||
""")
|
|
||||||
self.timeLabel.setFont(QFont("Arial", weight=QFont.Bold))
|
|
||||||
self.timeLabel.setAlignment(Qt.AlignmentFlag.AlignRight)
|
|
||||||
self.timeLabel.setSizePolicy(
|
|
||||||
QSizePolicy.Policy.Expanding, # 水平方向尽可能的占据布局中可用的空间
|
|
||||||
QSizePolicy.Policy.Fixed # 垂直方向固定为固定高度
|
|
||||||
)
|
|
||||||
self.mainLayout.addWidget(self.timeLabel, 0)
|
|
||||||
|
|
||||||
def _init_status_container(self):
|
def _init_status_container(self):
|
||||||
"""初始化核心状态监控容器(包含状态组和操作按钮)"""
|
"""初始化核心状态监控容器(包含状态组和操作按钮)"""
|
||||||
self.bigContainer = QFrame()
|
self.bigContainer = QFrame()
|
||||||
self.bigContainer.setStyleSheet("""
|
self.bigContainer.setStyleSheet("""
|
||||||
QFrame {
|
QFrame {
|
||||||
background-color: #f0f0f0;
|
background-color: #1E1E1E;
|
||||||
border: 2px solid #cccccc;
|
border: 2px solid #333333;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
@ -93,7 +79,7 @@ class StatusMonitor(QWidget):
|
|||||||
self.mainLayout.addWidget(self.bigContainer, 1)
|
self.mainLayout.addWidget(self.bigContainer, 1)
|
||||||
|
|
||||||
def _init_status_groups(self, parent_layout):
|
def _init_status_groups(self, parent_layout):
|
||||||
"""初始化左右状态组(包含4个状态项)"""
|
"""初始化左右信息(各包含5个状态项)"""
|
||||||
statusWidget = QWidget()
|
statusWidget = QWidget()
|
||||||
statusLayout = QHBoxLayout(statusWidget)
|
statusLayout = QHBoxLayout(statusWidget)
|
||||||
statusLayout.setContentsMargins(0, 0, 0, 0)
|
statusLayout.setContentsMargins(0, 0, 0, 0)
|
||||||
@ -109,15 +95,31 @@ class StatusMonitor(QWidget):
|
|||||||
rightLayout.setSpacing(15)
|
rightLayout.setSpacing(15)
|
||||||
rightLayout.setContentsMargins(0, 0, 0, 0)
|
rightLayout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
statusNames = ["盖板状态", "液压对齐状态", "LED状态", "按键状态"]
|
# 左边5个状态项及对应初始值
|
||||||
|
leftStatusInfo = [
|
||||||
|
{"name": "任务单号", "value": "20250706-01"},
|
||||||
|
{"name": "工程名称", "value": "18号线二期工程"},
|
||||||
|
{"name": "区间段", "value": "DK12+345-DK13+678"},
|
||||||
|
{"name": "坍落度", "value": "180mm"},
|
||||||
|
{"name": "配合比编号", "value": "PB-001"}
|
||||||
|
]
|
||||||
|
# 右边5个状态项及对应初始值
|
||||||
|
rightStatusInfo = [
|
||||||
|
{"name": "要料状态", "value": "未要料"},
|
||||||
|
{"name": "要料标号", "value": "C50"},
|
||||||
|
{"name": "要料方量", "value": "0m³"},
|
||||||
|
{"name": "要料时间", "value": "无"},
|
||||||
|
{"name": "小车状态", "value": "待命"}
|
||||||
|
]
|
||||||
self.statusWidgets = []
|
self.statusWidgets = []
|
||||||
|
|
||||||
for i, name in enumerate(statusNames):
|
# 处理左边状态项
|
||||||
|
for info in leftStatusInfo:
|
||||||
statusItem = QFrame()
|
statusItem = QFrame()
|
||||||
statusItem.setStyleSheet("""
|
statusItem.setStyleSheet("""
|
||||||
QFrame {
|
QFrame {
|
||||||
background-color: white;
|
background-color: #2D2D2D;
|
||||||
border: 1px solid #d0d0d0;
|
border: 1px solid #444444;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
@ -134,30 +136,30 @@ class StatusMonitor(QWidget):
|
|||||||
QLabel {
|
QLabel {
|
||||||
background-color: #9E9E9E;
|
background-color: #9E9E9E;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 2px solid #757575;
|
border: 2px solid #555555;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# 状态名称标签
|
# 状态名称标签
|
||||||
nameLabel = QLabel(name)
|
nameLabel = QLabel(info["name"])
|
||||||
nameLabel.setStyleSheet("font-size: 14px; color: #333333;")
|
nameLabel.setStyleSheet("font-size: 14px; color: #FFFFFF;")
|
||||||
nameLabel.setFont(QFont("Microsoft YaHei", 12))
|
nameLabel.setFont(QFont("Microsoft YaHei", 12))
|
||||||
|
|
||||||
# 状态值标签
|
# 状态值标签
|
||||||
valueLabel = QLabel("否")
|
valueLabel = QLabel(info["value"])
|
||||||
valueLabel.setStyleSheet("""
|
valueLabel.setStyleSheet("""
|
||||||
QLabel {
|
QLabel {
|
||||||
font-size: 18px;
|
font-size: 16px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #D32F2F;
|
color: #FFFFFF;
|
||||||
background-color: #FFEBEE;
|
background-color: #3D3D3D;
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #FFCDD2;
|
border: 1px solid #555555;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
valueLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
valueLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
valueLabel.setMinimumWidth(60)
|
valueLabel.setMinimumWidth(80)
|
||||||
|
|
||||||
itemLayout.addWidget(indicator)
|
itemLayout.addWidget(indicator)
|
||||||
itemLayout.addSpacing(10)
|
itemLayout.addSpacing(10)
|
||||||
@ -169,13 +171,75 @@ class StatusMonitor(QWidget):
|
|||||||
'indicator': indicator,
|
'indicator': indicator,
|
||||||
'nameLabel': nameLabel,
|
'nameLabel': nameLabel,
|
||||||
'valueLabel': valueLabel,
|
'valueLabel': valueLabel,
|
||||||
'status': False
|
'status': False,
|
||||||
|
'initial_value': info["value"]
|
||||||
})
|
})
|
||||||
|
|
||||||
if i % 2 == 0:
|
leftLayout.addWidget(statusItem)
|
||||||
leftLayout.addWidget(statusItem)
|
|
||||||
else:
|
# 处理右边状态项
|
||||||
rightLayout.addWidget(statusItem)
|
for info in rightStatusInfo:
|
||||||
|
statusItem = QFrame()
|
||||||
|
statusItem.setStyleSheet("""
|
||||||
|
QFrame {
|
||||||
|
background-color: #2D2D2D;
|
||||||
|
border: 1px solid #444444;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
statusItem.setFixedHeight(80)
|
||||||
|
|
||||||
|
itemLayout = QHBoxLayout(statusItem)
|
||||||
|
itemLayout.setContentsMargins(10, 5, 10, 5)
|
||||||
|
|
||||||
|
# 状态指示灯
|
||||||
|
indicator = QLabel()
|
||||||
|
indicator.setFixedSize(20, 20)
|
||||||
|
indicator.setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
background-color: #9E9E9E;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 2px solid #555555;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 状态名称标签
|
||||||
|
nameLabel = QLabel(info["name"])
|
||||||
|
nameLabel.setStyleSheet("font-size: 14px; color: #FFFFFF;")
|
||||||
|
nameLabel.setFont(QFont("Microsoft YaHei", 12))
|
||||||
|
|
||||||
|
# 状态值标签
|
||||||
|
valueLabel = QLabel(info["value"])
|
||||||
|
valueLabel.setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #FFFFFF;
|
||||||
|
background-color: #3D3D3D;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #555555;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
valueLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
valueLabel.setMinimumWidth(80)
|
||||||
|
|
||||||
|
itemLayout.addWidget(indicator)
|
||||||
|
itemLayout.addSpacing(10)
|
||||||
|
itemLayout.addWidget(nameLabel)
|
||||||
|
itemLayout.addStretch()
|
||||||
|
itemLayout.addWidget(valueLabel)
|
||||||
|
|
||||||
|
self.statusWidgets.append({
|
||||||
|
'indicator': indicator,
|
||||||
|
'nameLabel': nameLabel,
|
||||||
|
'valueLabel': valueLabel,
|
||||||
|
'status': False,
|
||||||
|
'initial_value': info["value"]
|
||||||
|
})
|
||||||
|
|
||||||
|
rightLayout.addWidget(statusItem)
|
||||||
|
|
||||||
statusLayout.addWidget(leftGroup)
|
statusLayout.addWidget(leftGroup)
|
||||||
statusLayout.addStretch(1)
|
statusLayout.addStretch(1)
|
||||||
@ -184,22 +248,37 @@ class StatusMonitor(QWidget):
|
|||||||
parent_layout.addWidget(statusWidget)
|
parent_layout.addWidget(statusWidget)
|
||||||
|
|
||||||
def _init_operation_buttons(self, parent_layout):
|
def _init_operation_buttons(self, parent_layout):
|
||||||
"""初始化操作按钮(开始/重启/停止)"""
|
"""初始化操作按钮(下料完成/生产异常/生产取消)"""
|
||||||
buttonContainer = QWidget()
|
buttonContainer = QWidget()
|
||||||
buttonLayout = QHBoxLayout(buttonContainer)
|
buttonLayout = QHBoxLayout(buttonContainer)
|
||||||
buttonLayout.setContentsMargins(0, 20, 0, 0)
|
buttonLayout.setContentsMargins(0, 20, 0, 0)
|
||||||
buttonLayout.setSpacing(30)
|
buttonLayout.setSpacing(30)
|
||||||
|
|
||||||
self.startButton = QPushButton("开始")
|
# 按钮图标(需替换为实际图标路径)
|
||||||
self.restartButton = QPushButton("重启")
|
down_icon_path = "img.png"
|
||||||
self.stopButton = QPushButton("停止")
|
error_icon_path = "img.png"
|
||||||
|
cancel_icon_path = "img.png"
|
||||||
|
|
||||||
|
self.startButton = QPushButton("下料完成")
|
||||||
|
self.restartButton = QPushButton("生产异常")
|
||||||
|
self.stopButton = QPushButton("生产取消")
|
||||||
|
|
||||||
|
# 设置按钮图标
|
||||||
|
self.startButton.setIcon(QIcon(down_icon_path))
|
||||||
|
self.restartButton.setIcon(QIcon(error_icon_path))
|
||||||
|
self.stopButton.setIcon(QIcon(cancel_icon_path))
|
||||||
|
|
||||||
|
# 设置图标大小
|
||||||
|
self.startButton.setIconSize(QSize(20, 20))
|
||||||
|
self.restartButton.setIconSize(QSize(20, 20))
|
||||||
|
self.stopButton.setIconSize(QSize(20, 20))
|
||||||
|
|
||||||
button_base_style = """
|
button_base_style = """
|
||||||
QPushButton {
|
QPushButton {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
border-radius: 6px;
|
border-radius: 15px;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
}
|
}
|
||||||
@ -213,25 +292,25 @@ class StatusMonitor(QWidget):
|
|||||||
|
|
||||||
self.startButton.setStyleSheet(button_base_style + """
|
self.startButton.setStyleSheet(button_base_style + """
|
||||||
QPushButton {
|
QPushButton {
|
||||||
background-color: #4CAF50;
|
background-color: #00796B;
|
||||||
color: white;
|
color: white;
|
||||||
border-color: #2E7D32;
|
border-color: #004D40;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
self.restartButton.setStyleSheet(button_base_style + """
|
self.restartButton.setStyleSheet(button_base_style + """
|
||||||
QPushButton {
|
QPushButton {
|
||||||
background-color: #FF9800;
|
background-color: #E65100;
|
||||||
color: white;
|
color: white;
|
||||||
border-color: #F57C00;
|
border-color: #BF360C;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
self.stopButton.setStyleSheet(button_base_style + """
|
self.stopButton.setStyleSheet(button_base_style + """
|
||||||
QPushButton {
|
QPushButton {
|
||||||
background-color: #F44336;
|
background-color: #C62828;
|
||||||
color: white;
|
color: white;
|
||||||
border-color: #D32F2F;
|
border-color: #8E0000;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
@ -266,11 +345,36 @@ class StatusMonitor(QWidget):
|
|||||||
|
|
||||||
def get_current_time(self):
|
def get_current_time(self):
|
||||||
"""获取格式化的当前时间"""
|
"""获取格式化的当前时间"""
|
||||||
return f"🕒 当前时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
|
return datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
def update_time(self):
|
def update_time(self):
|
||||||
"""更新时间显示"""
|
"""更新时间显示并触发重绘"""
|
||||||
self.timeLabel.setText(self.get_current_time())
|
self.current_datetime = self.get_current_time()
|
||||||
|
self.update() # 触发paintEvent重绘
|
||||||
|
|
||||||
|
def paintEvent(self, event):
|
||||||
|
"""重写绘画事件,在右上角绘制日期时间文本"""
|
||||||
|
super().paintEvent(event) # 调用父类方法保持原有绘制
|
||||||
|
|
||||||
|
# 创建QPainter对象
|
||||||
|
painter = QPainter(self)
|
||||||
|
painter.setRenderHint(QPainter.RenderHint.TextAntialiasing) # 文本抗锯齿
|
||||||
|
|
||||||
|
# 设置字体
|
||||||
|
font = QFont("Arial", 12, QFont.Bold)
|
||||||
|
painter.setFont(font)
|
||||||
|
|
||||||
|
# 设置文本颜色
|
||||||
|
painter.setPen(QColor("#00FF9D"))
|
||||||
|
|
||||||
|
# 计算文本位置(右上角,留出边距)
|
||||||
|
text = f"🕒 {self.current_datetime}"
|
||||||
|
text_rect = painter.boundingRect(self.rect(), Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop, text)
|
||||||
|
x = self.width() - text_rect.width() - 15 # 右边距15px
|
||||||
|
y = 15 # 上边距15px
|
||||||
|
|
||||||
|
# 绘制文本
|
||||||
|
painter.drawText(x, y + text_rect.height(), text)
|
||||||
|
|
||||||
def simulate_mcu_query(self):
|
def simulate_mcu_query(self):
|
||||||
"""模拟单片机状态查询"""
|
"""模拟单片机状态查询"""
|
||||||
@ -288,19 +392,19 @@ class StatusMonitor(QWidget):
|
|||||||
QLabel {
|
QLabel {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #2E7D32;
|
color: #00E676;
|
||||||
background-color: #E8F5E9;
|
background-color: #1E3A3A;
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #C8E6C9;
|
border: 1px solid #00796B;
|
||||||
min-width: 60px;
|
min-width: 60px;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
widget['indicator'].setStyleSheet("""
|
widget['indicator'].setStyleSheet("""
|
||||||
QLabel {
|
QLabel {
|
||||||
background-color: #4CAF50;
|
background-color: #00E676;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 2px solid #2E7D32;
|
border: 2px solid #00796B;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
else:
|
else:
|
||||||
@ -310,19 +414,19 @@ class StatusMonitor(QWidget):
|
|||||||
QLabel {
|
QLabel {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #D32F2F;
|
color: #FF5252;
|
||||||
background-color: #FFEBEE;
|
background-color: #3D2B2B;
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #FFCDD2;
|
border: 1px solid #5C3636;
|
||||||
min-width: 60px;
|
min-width: 60px;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
widget['indicator'].setStyleSheet("""
|
widget['indicator'].setStyleSheet("""
|
||||||
QLabel {
|
QLabel {
|
||||||
background-color: #F44336;
|
background-color: #FF5252;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 2px solid #D32F2F;
|
border: 2px solid #C62828;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
@ -351,19 +455,19 @@ class StatusMonitor(QWidget):
|
|||||||
QLabel {
|
QLabel {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #D32F2F;
|
color: #FF5252;
|
||||||
background-color: #FFEBEE;
|
background-color: #3D2B2B;
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
border: 1px solid #FFCDD2;
|
border: 1px solid #5C3636;
|
||||||
min-width: 60px;
|
min-width: 60px;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
widget['indicator'].setStyleSheet("""
|
widget['indicator'].setStyleSheet("""
|
||||||
QLabel {
|
QLabel {
|
||||||
background-color: #F44336;
|
background-color: #FF5252;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 2px solid #D32F2F;
|
border: 2px solid #C62828;
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
# 重启后自动开始
|
# 重启后自动开始
|
||||||
|
|||||||
475
test.py
Normal file
475
test.py
Normal file
@ -0,0 +1,475 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
# @Time : 2025/9/10 11:29
|
||||||
|
# @Author : reenrr
|
||||||
|
# @File : test.py
|
||||||
|
'''
|
||||||
|
import sys
|
||||||
|
from PySide6.QtWidgets import (
|
||||||
|
QApplication, QWidget, QVBoxLayout, QHBoxLayout,
|
||||||
|
QLabel, QFrame, QSizePolicy, QPushButton
|
||||||
|
)
|
||||||
|
from PySide6.QtCore import Qt, QTimer, QPoint, QSize
|
||||||
|
from PySide6.QtGui import QFont, QPainter, QColor, QPen, QIcon
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class StatusMonitor(QWidget):
|
||||||
|
"""
|
||||||
|
中交三航精准布料浇筑要料系统 - 主界面类(深色主题)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
"""构造函数:初始化主界面的UI布局、控件和定时器"""
|
||||||
|
super().__init__(parent=parent)
|
||||||
|
self.is_running = False # 系统运行状态标记
|
||||||
|
self.current_datetime = self.get_current_time() # 当前日期时间
|
||||||
|
|
||||||
|
# 窗口基础设置
|
||||||
|
self.setWindowTitle("中交三航精准布料浇筑要料系统")
|
||||||
|
self.setGeometry(100, 100, 800, 500) # 设置窗口位置和大小
|
||||||
|
self.setStyleSheet("background-color: #121212;") # 窗口背景设为深黑色
|
||||||
|
|
||||||
|
# 初始化主布局(垂直布局)
|
||||||
|
self.mainLayout = QVBoxLayout(self)
|
||||||
|
self.mainLayout.setContentsMargins(10, 40, 10, 10) # 上边距留空用于显示日期
|
||||||
|
self.mainLayout.setSpacing(10) # 相邻控件的间距
|
||||||
|
|
||||||
|
# 初始化界面组件
|
||||||
|
self._init_title_label()
|
||||||
|
self._init_status_container()
|
||||||
|
self._init_timers()
|
||||||
|
|
||||||
|
def _init_title_label(self):
|
||||||
|
"""初始化系统标题标签"""
|
||||||
|
titleLabel = QLabel("中交三航精准布料浇筑要料系统")
|
||||||
|
titleLabel.setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
color: #00FF9D;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
titleLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
titleLabel.setFont(QFont("Microsoft YaHei", 24, QFont.Bold))
|
||||||
|
self.mainLayout.addWidget(titleLabel)
|
||||||
|
|
||||||
|
def _init_status_container(self):
|
||||||
|
"""初始化核心状态监控容器(包含状态组和操作按钮)"""
|
||||||
|
self.bigContainer = QFrame()
|
||||||
|
self.bigContainer.setStyleSheet("""
|
||||||
|
QFrame {
|
||||||
|
background-color: #1E1E1E;
|
||||||
|
border: 2px solid #333333;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
self.bigContainer.setSizePolicy(
|
||||||
|
QSizePolicy.Policy.Expanding,
|
||||||
|
QSizePolicy.Policy.Expanding
|
||||||
|
)
|
||||||
|
|
||||||
|
containerLayout = QVBoxLayout(self.bigContainer)
|
||||||
|
containerLayout.setContentsMargins(20, 20, 20, 20)
|
||||||
|
|
||||||
|
self._init_status_groups(containerLayout)
|
||||||
|
self._init_operation_buttons(containerLayout)
|
||||||
|
|
||||||
|
self.mainLayout.addWidget(self.bigContainer, 1)
|
||||||
|
|
||||||
|
def _init_status_groups(self, parent_layout):
|
||||||
|
"""初始化左右信息(各包含5个状态项)"""
|
||||||
|
statusWidget = QWidget()
|
||||||
|
statusLayout = QHBoxLayout(statusWidget)
|
||||||
|
statusLayout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
statusLayout.setSpacing(30)
|
||||||
|
|
||||||
|
leftGroup = QWidget()
|
||||||
|
leftLayout = QVBoxLayout(leftGroup)
|
||||||
|
leftLayout.setSpacing(15)
|
||||||
|
leftLayout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
|
rightGroup = QWidget()
|
||||||
|
rightLayout = QVBoxLayout(rightGroup)
|
||||||
|
rightLayout.setSpacing(15)
|
||||||
|
rightLayout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
|
# 左边5个状态项及对应初始值
|
||||||
|
leftStatusInfo = [
|
||||||
|
{"name": "任务单号", "value": "20250706-01"},
|
||||||
|
{"name": "工程名称", "value": "18号线二期工程"},
|
||||||
|
{"name": "区间段", "value": "DK12+345-DK13+678"},
|
||||||
|
{"name": "坍落度", "value": "180mm"},
|
||||||
|
{"name": "配合比编号", "value": "PB-001"}
|
||||||
|
]
|
||||||
|
# 右边5个状态项及对应初始值
|
||||||
|
rightStatusInfo = [
|
||||||
|
{"name": "要料状态", "value": "未要料"},
|
||||||
|
{"name": "要料标号", "value": "C50"},
|
||||||
|
{"name": "要料方量", "value": "0m³"},
|
||||||
|
{"name": "要料时间", "value": "无"},
|
||||||
|
{"name": "小车状态", "value": "待命"}
|
||||||
|
]
|
||||||
|
self.statusWidgets = []
|
||||||
|
|
||||||
|
# 处理左边状态项
|
||||||
|
for info in leftStatusInfo:
|
||||||
|
statusItem = QFrame()
|
||||||
|
statusItem.setStyleSheet("""
|
||||||
|
QFrame {
|
||||||
|
background-color: #2D2D2D;
|
||||||
|
border: 1px solid #444444;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
statusItem.setFixedHeight(80)
|
||||||
|
|
||||||
|
itemLayout = QHBoxLayout(statusItem)
|
||||||
|
itemLayout.setContentsMargins(10, 5, 10, 5)
|
||||||
|
|
||||||
|
# 状态指示灯
|
||||||
|
indicator = QLabel()
|
||||||
|
indicator.setFixedSize(20, 20)
|
||||||
|
indicator.setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
background-color: #9E9E9E;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 2px solid #555555;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 状态名称标签
|
||||||
|
nameLabel = QLabel(info["name"])
|
||||||
|
nameLabel.setStyleSheet("font-size: 14px; color: #FFFFFF;")
|
||||||
|
nameLabel.setFont(QFont("Microsoft YaHei", 12))
|
||||||
|
|
||||||
|
# 状态值标签(去掉边框)
|
||||||
|
valueLabel = QLabel(info["value"])
|
||||||
|
valueLabel.setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #FFFFFF;
|
||||||
|
background-color: #3D3D3D;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
valueLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
valueLabel.setMinimumWidth(80)
|
||||||
|
|
||||||
|
itemLayout.addWidget(indicator)
|
||||||
|
itemLayout.addSpacing(10)
|
||||||
|
itemLayout.addWidget(nameLabel)
|
||||||
|
itemLayout.addStretch()
|
||||||
|
itemLayout.addWidget(valueLabel)
|
||||||
|
|
||||||
|
self.statusWidgets.append({
|
||||||
|
'indicator': indicator,
|
||||||
|
'nameLabel': nameLabel,
|
||||||
|
'valueLabel': valueLabel,
|
||||||
|
'status': False,
|
||||||
|
'initial_value': info["value"]
|
||||||
|
})
|
||||||
|
|
||||||
|
leftLayout.addWidget(statusItem)
|
||||||
|
|
||||||
|
# 处理右边状态项
|
||||||
|
for info in rightStatusInfo:
|
||||||
|
statusItem = QFrame()
|
||||||
|
statusItem.setStyleSheet("""
|
||||||
|
QFrame {
|
||||||
|
background-color: #2D2D2D;
|
||||||
|
border: 1px solid #444444;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
statusItem.setFixedHeight(80)
|
||||||
|
|
||||||
|
itemLayout = QHBoxLayout(statusItem)
|
||||||
|
itemLayout.setContentsMargins(10, 5, 10, 5)
|
||||||
|
|
||||||
|
# 状态指示灯
|
||||||
|
indicator = QLabel()
|
||||||
|
indicator.setFixedSize(20, 20)
|
||||||
|
indicator.setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
background-color: #9E9E9E;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 2px solid #555555;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 状态名称标签
|
||||||
|
nameLabel = QLabel(info["name"])
|
||||||
|
nameLabel.setStyleSheet("font-size: 14px; color: #FFFFFF;")
|
||||||
|
nameLabel.setFont(QFont("Microsoft YaHei", 12))
|
||||||
|
|
||||||
|
# 状态值标签(去掉边框)
|
||||||
|
valueLabel = QLabel(info["value"])
|
||||||
|
valueLabel.setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #FFFFFF;
|
||||||
|
background-color: #3D3D3D;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
valueLabel.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
valueLabel.setMinimumWidth(80)
|
||||||
|
|
||||||
|
itemLayout.addWidget(indicator)
|
||||||
|
itemLayout.addSpacing(10)
|
||||||
|
itemLayout.addWidget(nameLabel)
|
||||||
|
itemLayout.addStretch()
|
||||||
|
itemLayout.addWidget(valueLabel)
|
||||||
|
|
||||||
|
self.statusWidgets.append({
|
||||||
|
'indicator': indicator,
|
||||||
|
'nameLabel': nameLabel,
|
||||||
|
'valueLabel': valueLabel,
|
||||||
|
'status': False,
|
||||||
|
'initial_value': info["value"]
|
||||||
|
})
|
||||||
|
|
||||||
|
rightLayout.addWidget(statusItem)
|
||||||
|
|
||||||
|
statusLayout.addWidget(leftGroup)
|
||||||
|
statusLayout.addStretch(1)
|
||||||
|
statusLayout.addWidget(rightGroup)
|
||||||
|
|
||||||
|
parent_layout.addWidget(statusWidget)
|
||||||
|
|
||||||
|
def _init_operation_buttons(self, parent_layout):
|
||||||
|
"""初始化操作按钮(下料完成/生产异常/生产取消)"""
|
||||||
|
buttonContainer = QWidget()
|
||||||
|
buttonLayout = QHBoxLayout(buttonContainer)
|
||||||
|
buttonLayout.setContentsMargins(0, 20, 0, 0)
|
||||||
|
buttonLayout.setSpacing(30)
|
||||||
|
|
||||||
|
# 按钮图标(需替换为实际图标路径)
|
||||||
|
down_icon_path = "img.png"
|
||||||
|
error_icon_path = "img.png"
|
||||||
|
cancel_icon_path = "img.png"
|
||||||
|
|
||||||
|
self.startButton = QPushButton("下料完成")
|
||||||
|
self.restartButton = QPushButton("生产异常")
|
||||||
|
self.stopButton = QPushButton("生产取消")
|
||||||
|
|
||||||
|
# 设置按钮图标
|
||||||
|
self.startButton.setIcon(QIcon(down_icon_path))
|
||||||
|
self.restartButton.setIcon(QIcon(error_icon_path))
|
||||||
|
self.stopButton.setIcon(QIcon(cancel_icon_path))
|
||||||
|
|
||||||
|
# 设置图标大小
|
||||||
|
self.startButton.setIconSize(QSize(20, 20))
|
||||||
|
self.restartButton.setIconSize(QSize(20, 20))
|
||||||
|
self.stopButton.setIconSize(QSize(20, 20))
|
||||||
|
|
||||||
|
button_base_style = """
|
||||||
|
QPushButton {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 15px;
|
||||||
|
border: 1px solid;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
QPushButton:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
QPushButton:pressed {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.startButton.setStyleSheet(button_base_style + """
|
||||||
|
QPushButton {
|
||||||
|
background-color: #00796B;
|
||||||
|
color: white;
|
||||||
|
border-color: #004D40;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
self.restartButton.setStyleSheet(button_base_style + """
|
||||||
|
QPushButton {
|
||||||
|
background-color: #E65100;
|
||||||
|
color: white;
|
||||||
|
border-color: #BF360C;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
self.stopButton.setStyleSheet(button_base_style + """
|
||||||
|
QPushButton {
|
||||||
|
background-color: #C62828;
|
||||||
|
color: white;
|
||||||
|
border-color: #8E0000;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
button_font = QFont("Microsoft YaHei", 12, QFont.Bold)
|
||||||
|
self.startButton.setFont(button_font)
|
||||||
|
self.restartButton.setFont(button_font)
|
||||||
|
self.stopButton.setFont(button_font)
|
||||||
|
|
||||||
|
self.startButton.clicked.connect(self.on_start_clicked)
|
||||||
|
self.restartButton.clicked.connect(self.on_restart_clicked)
|
||||||
|
self.stopButton.clicked.connect(self.on_stop_clicked)
|
||||||
|
|
||||||
|
buttonLayout.addStretch(1)
|
||||||
|
buttonLayout.addWidget(self.startButton)
|
||||||
|
buttonLayout.addWidget(self.restartButton)
|
||||||
|
buttonLayout.addWidget(self.stopButton)
|
||||||
|
buttonLayout.addStretch(1)
|
||||||
|
|
||||||
|
parent_layout.addWidget(buttonContainer)
|
||||||
|
|
||||||
|
def _init_timers(self):
|
||||||
|
"""初始化定时器(时间更新+状态模拟)"""
|
||||||
|
# 时间更新定时器(每秒更新一次)
|
||||||
|
self.time_timer = QTimer()
|
||||||
|
self.time_timer.timeout.connect(self.update_time)
|
||||||
|
self.time_timer.start(1000)
|
||||||
|
|
||||||
|
# 状态模拟定时器(每3秒更新一次)
|
||||||
|
self.status_timer = QTimer()
|
||||||
|
self.status_timer.timeout.connect(self.simulate_mcu_query)
|
||||||
|
self.status_timer.start(3000)
|
||||||
|
|
||||||
|
def get_current_time(self):
|
||||||
|
"""获取格式化的当前时间"""
|
||||||
|
return datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
def update_time(self):
|
||||||
|
"""更新时间显示并触发重绘"""
|
||||||
|
self.current_datetime = self.get_current_time()
|
||||||
|
self.update() # 触发paintEvent重绘
|
||||||
|
|
||||||
|
def paintEvent(self, event):
|
||||||
|
"""重写绘画事件,在右上角绘制日期时间文本"""
|
||||||
|
super().paintEvent(event) # 调用父类方法保持原有绘制
|
||||||
|
|
||||||
|
# 创建QPainter对象
|
||||||
|
painter = QPainter(self)
|
||||||
|
painter.setRenderHint(QPainter.RenderHint.TextAntialiasing) # 文本抗锯齿
|
||||||
|
|
||||||
|
# 设置字体
|
||||||
|
font = QFont("Arial", 12, QFont.Bold)
|
||||||
|
painter.setFont(font)
|
||||||
|
|
||||||
|
# 设置文本颜色
|
||||||
|
painter.setPen(QColor("#00FF9D"))
|
||||||
|
|
||||||
|
# 计算文本位置(右上角,留出边距)
|
||||||
|
text = f"🕒 {self.current_datetime}"
|
||||||
|
text_rect = painter.boundingRect(self.rect(), Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop, text)
|
||||||
|
x = self.width() - text_rect.width() - 15 # 右边距15px
|
||||||
|
y = 15 # 上边距15px
|
||||||
|
|
||||||
|
# 绘制文本
|
||||||
|
painter.drawText(x, y + text_rect.height(), text)
|
||||||
|
|
||||||
|
def simulate_mcu_query(self):
|
||||||
|
"""模拟单片机状态查询"""
|
||||||
|
import random # 仅用于模拟,实际项目替换为真实通信逻辑
|
||||||
|
|
||||||
|
if self.is_running:
|
||||||
|
for widget in self.statusWidgets:
|
||||||
|
status = random.choice([True, False])
|
||||||
|
widget['status'] = status
|
||||||
|
|
||||||
|
if status:
|
||||||
|
# 状态为"是"时的样式
|
||||||
|
widget['valueLabel'].setText("是")
|
||||||
|
widget['valueLabel'].setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #00E676;
|
||||||
|
background-color: #1E3A3A;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #00796B;
|
||||||
|
min-width: 60px;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
widget['indicator'].setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
background-color: #00E676;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 2px solid #00796B;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
else:
|
||||||
|
# 状态为"否"时的样式
|
||||||
|
widget['valueLabel'].setText("否")
|
||||||
|
widget['valueLabel'].setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #FF5252;
|
||||||
|
background-color: #3D2B2B;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #5C3636;
|
||||||
|
min-width: 60px;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
widget['indicator'].setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
background-color: #FF5252;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 2px solid #C62828;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
def on_start_clicked(self):
|
||||||
|
"""开始按钮点击事件"""
|
||||||
|
if not self.is_running:
|
||||||
|
self.is_running = True
|
||||||
|
print("系统已启动,开始监控状态...")
|
||||||
|
self.simulate_mcu_query() # 启动时立即更新一次状态
|
||||||
|
|
||||||
|
def on_stop_clicked(self):
|
||||||
|
"""停止按钮点击事件"""
|
||||||
|
if self.is_running:
|
||||||
|
self.is_running = False
|
||||||
|
print("系统已停止,状态监控暂停...")
|
||||||
|
|
||||||
|
def on_restart_clicked(self):
|
||||||
|
"""重启按钮点击事件"""
|
||||||
|
print("系统正在重启...")
|
||||||
|
self.is_running = False
|
||||||
|
# 重置所有状态为"否"
|
||||||
|
for widget in self.statusWidgets:
|
||||||
|
widget['status'] = False
|
||||||
|
widget['valueLabel'].setText("否")
|
||||||
|
widget['valueLabel'].setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #FF5252;
|
||||||
|
background-color: #3D2B2B;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #5C3636;
|
||||||
|
min-width: 60px;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
widget['indicator'].setStyleSheet("""
|
||||||
|
QLabel {
|
||||||
|
background-color: #FF5252;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 2px solid #C62828;
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
# 重启后自动开始
|
||||||
|
QTimer.singleShot(1000, self.on_start_clicked)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
window = StatusMonitor()
|
||||||
|
window.show()
|
||||||
|
sys.exit(app.exec())
|
||||||
Reference in New Issue
Block a user