2025-11-16 11:58:22 +08:00
|
|
|
|
# coding: utf-8
|
|
|
|
|
|
from typing import List
|
|
|
|
|
|
from PySide6.QtCore import Qt, Signal, QEasingCurve, QUrl, QSize, QTimer, QEvent
|
|
|
|
|
|
from PySide6.QtGui import QIcon, QDesktopServices, QColor, QPalette, QBrush, QImage
|
|
|
|
|
|
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QVBoxLayout,
|
|
|
|
|
|
QFrame, QWidget, QSpacerItem, QSizePolicy, QMainWindow, QPushButton)
|
|
|
|
|
|
|
|
|
|
|
|
from system_nav_bar import SystemNavBar
|
|
|
|
|
|
from bottom_control_widget import BottomControlWidget
|
|
|
|
|
|
from weight_dialog import WeightDetailsDialog
|
|
|
|
|
|
from tcp_client import TcpClient
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MainWindow(QWidget):
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
|
super().__init__()
|
|
|
|
|
|
self.initWindow()
|
|
|
|
|
|
self.createSubWidgets() # 创建子部件
|
|
|
|
|
|
self.setupLayout() # 设置布局
|
|
|
|
|
|
self.tcp_client = TcpClient(self) # 创建 TCP 客户端
|
|
|
|
|
|
self.bind_signals() # 绑定信号槽
|
|
|
|
|
|
|
|
|
|
|
|
def initWindow(self):
|
|
|
|
|
|
"""初始化窗口基本属性"""
|
|
|
|
|
|
self.setWindowTitle("中交三航主界面") # 设置窗口标题
|
|
|
|
|
|
# 触摸屏尺寸为 1280*800
|
|
|
|
|
|
self.setMinimumSize(1280, 800)
|
|
|
|
|
|
self.setObjectName("MainWindow")
|
|
|
|
|
|
|
|
|
|
|
|
# Qt.FramelessWindowHint
|
|
|
|
|
|
self.setWindowFlags(Qt.FramelessWindowHint) # 无边框窗口
|
|
|
|
|
|
|
|
|
|
|
|
# 设置主界面背景图片
|
|
|
|
|
|
try:
|
|
|
|
|
|
self.background_image = QImage("主界面背景.png")
|
|
|
|
|
|
if self.background_image.isNull():
|
|
|
|
|
|
raise Exception("图片为空,可能路径错误或格式不支持")
|
|
|
|
|
|
# print("图片加载成功")
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"主界面背景图片加载失败: {e}")
|
|
|
|
|
|
self.background_image = None
|
|
|
|
|
|
return # 加载背景失败
|
|
|
|
|
|
|
|
|
|
|
|
self.update_background()
|
|
|
|
|
|
|
|
|
|
|
|
def createSubWidgets(self):
|
|
|
|
|
|
"""创建所有子部件实例"""
|
|
|
|
|
|
self.system_nav_bar = SystemNavBar() # 最上方:系统导航栏
|
|
|
|
|
|
self.bottom_control_widget = BottomControlWidget() # 最下方: 控制的按钮 (系统诊断、系统中心等)
|
|
|
|
|
|
|
|
|
|
|
|
# 上料斗、下料斗重量显示
|
|
|
|
|
|
self.weight_dialog1 = WeightDetailsDialog(self, title="上料斗重量")
|
|
|
|
|
|
self.weight_dialog2 = WeightDetailsDialog(self, title="下料斗重量")
|
|
|
|
|
|
|
|
|
|
|
|
def setupLayout(self):
|
|
|
|
|
|
"""设置垂直布局,从上到下排列部件"""
|
|
|
|
|
|
main_layout = QVBoxLayout(self) # 主布局:垂直布局
|
|
|
|
|
|
main_layout.setSpacing(0) # 部件间距0px
|
|
|
|
|
|
main_layout.setContentsMargins(0, 0, 0, 0) # 左上右下边距0px
|
|
|
|
|
|
|
|
|
|
|
|
# 添加最上方的 系统导航栏(包括系统标题、中交三航的logo等)
|
|
|
|
|
|
main_layout.addWidget(self.system_nav_bar, alignment=Qt.AlignTop)
|
|
|
|
|
|
# 添加中间内容区
|
|
|
|
|
|
main_layout.addWidget(self.weight_dialog1, alignment=Qt.AlignCenter)
|
|
|
|
|
|
main_layout.addWidget(self.weight_dialog2, alignment=Qt.AlignCenter)
|
|
|
|
|
|
# 关闭按钮
|
|
|
|
|
|
self.system_nav_bar.msg_container.close_btn.clicked.connect(self.close)
|
|
|
|
|
|
# 将布局应用到主窗口
|
|
|
|
|
|
self.setLayout(main_layout)
|
|
|
|
|
|
|
|
|
|
|
|
def update_background(self):
|
|
|
|
|
|
"""更新主界面背景图片"""
|
|
|
|
|
|
if self.background_image and not self.background_image.isNull():
|
|
|
|
|
|
palette = self.palette()
|
|
|
|
|
|
# 按当前窗口尺寸缩放图片
|
|
|
|
|
|
scaled_image = self.background_image.scaled(
|
|
|
|
|
|
self.size(),
|
|
|
|
|
|
Qt.IgnoreAspectRatio,
|
|
|
|
|
|
Qt.SmoothTransformation
|
|
|
|
|
|
)
|
|
|
|
|
|
palette.setBrush(QPalette.Window, QBrush(scaled_image))
|
|
|
|
|
|
self.setPalette(palette)
|
|
|
|
|
|
self.setAutoFillBackground(True)
|
|
|
|
|
|
|
|
|
|
|
|
def resizeEvent(self, e):
|
|
|
|
|
|
"""窗口大小变化时的回调"""
|
|
|
|
|
|
super().resizeEvent(e)
|
|
|
|
|
|
self.update_background() # 重新加载背景图片
|
|
|
|
|
|
|
|
|
|
|
|
def keyPressEvent(self, event):
|
|
|
|
|
|
if event.key() == Qt.Key_Escape: # 按下Esc键, 退出界面
|
|
|
|
|
|
self.close()
|
|
|
|
|
|
super().keyPressEvent(event)
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------
|
|
|
|
|
|
# TCP更新重量信息
|
|
|
|
|
|
# ---------------
|
|
|
|
|
|
def bind_signals(self):
|
|
|
|
|
|
"""绑定TCP信号到弹窗更新函数"""
|
|
|
|
|
|
self.tcp_client.weight_updated.connect(self.update_weight_dialogs) # 绑定更新重量信息的信号槽
|
2025-11-17 16:02:46 +08:00
|
|
|
|
# 连接状态信号:更新状态图标
|
2025-11-16 11:58:22 +08:00
|
|
|
|
self.tcp_client.connection_status_changed.connect(self.update_connection_status)
|
2025-11-17 16:02:46 +08:00
|
|
|
|
# 上料斗重量信息更新失败信号:更新状态图标
|
|
|
|
|
|
self.tcp_client.upper_weight_error.connect(self.upper_weight_status) # 重量信息更新失败信号
|
|
|
|
|
|
# 下料斗重量信息更新失败信号:更新状态图标
|
|
|
|
|
|
self.tcp_client.down_weight_error.connect(self.down_weight_status) # 重量信息更新失败信号
|
2025-11-16 11:58:22 +08:00
|
|
|
|
# 启动 TCP 连接
|
|
|
|
|
|
print(f"客户端启动,自动连接服务端{self.tcp_client.tcp_server_host}:{self.tcp_client.tcp_server_port}...")
|
|
|
|
|
|
self.tcp_client._connect_to_server()
|
|
|
|
|
|
|
2025-11-17 16:02:46 +08:00
|
|
|
|
def down_weight_status(self, is_error):
|
|
|
|
|
|
"""发送上料斗错误信息,更新连接状态"""
|
|
|
|
|
|
self.weight_dialog2._update_status_icon2(is_error)
|
|
|
|
|
|
|
|
|
|
|
|
def upper_weight_status(self, is_error):
|
|
|
|
|
|
"""发送下料斗错误信息,更新连接状态"""
|
|
|
|
|
|
self.weight_dialog1._update_status_icon2(is_error)
|
|
|
|
|
|
|
2025-11-16 11:58:22 +08:00
|
|
|
|
def update_connection_status(self, is_connected):
|
2025-11-17 16:02:46 +08:00
|
|
|
|
"""根据服务端是否连接,更新连接状态"""
|
|
|
|
|
|
self.weight_dialog1._update_status_icon1(is_connected)
|
|
|
|
|
|
self.weight_dialog2._update_status_icon1(is_connected)
|
2025-11-16 11:58:22 +08:00
|
|
|
|
|
|
|
|
|
|
def update_weight_dialogs(self, data):
|
|
|
|
|
|
"""更新上料斗、下料斗重量显示"""
|
|
|
|
|
|
# 上料斗重量(对应字段 hopper_up_weight,需与服务器一致)
|
|
|
|
|
|
up_weight = data.get("hopper_up_weight", 0)
|
|
|
|
|
|
self.weight_dialog1.update_weight(up_weight)
|
|
|
|
|
|
|
|
|
|
|
|
# 下料斗重量(对应字段 hopper_down_weight,需与服务器一致)
|
|
|
|
|
|
down_weight = data.get("hopper_down_weight", 0)
|
|
|
|
|
|
self.weight_dialog2.update_weight(down_weight)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
import sys
|
|
|
|
|
|
app = QApplication([])
|
|
|
|
|
|
window = MainWindow()
|
2025-11-17 16:02:46 +08:00
|
|
|
|
window.show() # 显示主界面
|
|
|
|
|
|
# window.showFullScreen() # 全屏显示主界面
|
2025-11-16 11:58:22 +08:00
|
|
|
|
sys.exit(app.exec())
|