Files
ReinLoopTest/ReinLoop/ui/connection_tab.py
2026-07-30 11:12:31 +08:00

178 lines
6.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# connection_tab.py
"""页面1Modbus TCP 连接参数设置"""
import os
from PySide6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QGridLayout,
QLabel, QLineEdit, QPushButton, QFrame,
QSizePolicy, QGraphicsDropShadowEffect
)
from PySide6.QtCore import Qt, QSize
from PySide6.QtGui import QColor, QIcon
_SRC_DIR = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", "src"))
# ==========================================
# 工具函数:创建带左侧蓝色竖线的 Section 卡片
# ==========================================
def _make_section_card(parent, title_text: str, colors: dict):
card = QFrame(parent)
card.setProperty("cssClass", "sectionCard")
card.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
# 添加微弱的模糊阴影效果
shadow = QGraphicsDropShadowEffect(card)
shadow.setColor(QColor(0, 0, 0, 12))
shadow.setBlurRadius(16)
shadow.setOffset(0, 4)
card.setGraphicsEffect(shadow)
outer = QVBoxLayout(card)
outer.setContentsMargins(0, 0, 0, 0)
outer.setSpacing(0)
# ---- 标题行(蓝色左竖线 + 标题文字) ----
title_row = QHBoxLayout()
title_row.setContentsMargins(20, 16, 20, 0)
title_row.setSpacing(10)
accent = QWidget()
accent.setProperty("cssClass", "sectionAccent")
accent.setFixedSize(4, 16)
title_row.addWidget(accent)
title_lbl = QLabel(title_text)
title_lbl.setProperty("cssClass", "sectionTitle")
title_row.addWidget(title_lbl)
title_row.addStretch()
outer.addLayout(title_row)
# ---- 内容区 ----
content_widget = QWidget()
content_widget.setStyleSheet("background-color: transparent;")
content_layout = QGridLayout(content_widget)
content_layout.setContentsMargins(20, 14, 20, 18)
content_layout.setHorizontalSpacing(0)
content_layout.setVerticalSpacing(10)
# 列0(标签)固定宽度,列1(输入框)拉伸
content_layout.setColumnMinimumWidth(0, 148)
content_layout.setColumnStretch(1, 1)
outer.addWidget(content_widget)
return card, content_layout
# ==========================================
# 工具函数:创建表单标签(左对齐)
# ==========================================
def _form_label(text: str, parent=None):
lbl = QLabel(text, parent)
lbl.setProperty("cssClass", "formLabel")
lbl.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
return lbl
class ConnectionTab(QWidget):
"""连接设置页面"""
def __init__(self, colors: dict, parent=None):
super().__init__(parent)
self.setProperty("cssClass", "tabPage")
self.colors = colors
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(20, 16, 20, 16)
main_layout.setSpacing(14)
# ==========================================
# Section: Modbus TCP
# ==========================================
tcp_card, tcp_layout = _make_section_card(self, "Modbus TCP", colors)
self._build_tcp_section(tcp_layout)
main_layout.addWidget(tcp_card)
# ==========================================
# 按钮组
# ==========================================
btn_row = QHBoxLayout()
btn_row.setContentsMargins(0, 4, 0, 0)
btn_row.setSpacing(12)
# 连接设备按钮
self.connect_btn = QPushButton(" 连接设备")
self.connect_btn.setObjectName("connect_btn")
self.connect_btn.setIcon(QIcon(os.path.join(_SRC_DIR, "connect_device.svg")))
self.connect_btn.setIconSize(QSize(18, 18))
self.connect_btn.setCursor(Qt.PointingHandCursor)
# 保存按钮引用(connect/disconnect 切换文字时使用)
self._connect_text_lbl = self.connect_btn
btn_row.addWidget(self.connect_btn)
btn_row.addStretch()
main_layout.addLayout(btn_row)
main_layout.addStretch()
# ==========================================
# Modbus TCP 表单
# ==========================================
def _build_tcp_section(self, grid: QGridLayout):
row = 0
grid.addWidget(_form_label("模块地址:", self), row, 0)
self.tcp_ip_entry = QLineEdit("192.168.1.12")
self.tcp_ip_entry.setPlaceholderText("输入模块 IP地址")
grid.addWidget(self.tcp_ip_entry, row, 1)
row += 1
grid.addWidget(_form_label("端口:", self), row, 0)
self.tcp_port_entry = QLineEdit("502")
self.tcp_port_entry.setPlaceholderText("默认502")
grid.addWidget(self.tcp_port_entry, row, 1)
row += 1
grid.addWidget(_form_label("读取压力寄存器地址:", self), row, 0)
self.pressure_addr_entry = QLineEdit("0")
self.pressure_addr_entry.setPlaceholderText("寄存器地址")
grid.addWidget(self.pressure_addr_entry, row, 1)
row += 1
grid.addWidget(_form_label("电机地址:", self), row, 0)
self.motor_addr_entry = QLineEdit("0")
self.motor_addr_entry.setPlaceholderText("电机模拟量通道地址")
grid.addWidget(self.motor_addr_entry, row, 1)
row += 1
grid.addWidget(_form_label("流量计地址:", self), row, 0)
self.flowmeter_addr_entry = QLineEdit("1")
self.flowmeter_addr_entry.setPlaceholderText("留空则使用手动输入流量")
grid.addWidget(self.flowmeter_addr_entry, row, 1)
row += 1
grid.addWidget(_form_label("压力表量程:", self), row, 0)
self.pressure_range_entry = QLineEdit("400")
self.pressure_range_entry.setPlaceholderText("压力传感器量程上限")
grid.addWidget(self.pressure_range_entry, row, 1)
row += 1
grid.addWidget(_form_label("流量计量程:", self), row, 0)
self.flow_range_entry = QLineEdit("300")
self.flow_range_entry.setPlaceholderText("流量计量程上限")
grid.addWidget(self.flow_range_entry, row, 1)
# ---- 公开方法 ----
def get_connection_params(self) -> dict:
flow_str = self.flowmeter_addr_entry.text().strip()
return {
"tcp_ip": self.tcp_ip_entry.text().strip(),
"tcp_port": int(self.tcp_port_entry.text() or "502"),
"pressure_addr": int(self.pressure_addr_entry.text() or "504"),
"motor_addr": int(self.motor_addr_entry.text() or "0"),
"flowmeter_addr": int(flow_str) if flow_str else None,
"pressure_range": float(self.pressure_range_entry.text() or "400"),
"flow_range": float(self.flow_range_entry.text() or "300"),
}