这是使用PyQT5作为UI的首次提交,将后端和UI合并到1个工程中,统一使用了Python,没有使用JS和HTML
This commit is contained in:
253
UI/views/dut_form_dialog.py
Normal file
253
UI/views/dut_form_dialog.py
Normal file
@@ -0,0 +1,253 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
DUT表单对话框(全局复用)
|
||||
- 新建/编辑公用一个对话框,根据模式禁用部分字段
|
||||
- 数据以 dict(dut_form) 形式在模块间传递
|
||||
- 设备分配为二级选择:机台 -> 通道
|
||||
"""
|
||||
|
||||
from PyQt5.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QFormLayout, QLineEdit, QComboBox,
|
||||
QTextEdit, QPushButton, QLabel, QWidget
|
||||
)
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
|
||||
class DUTFormDialog(QDialog):
|
||||
def __init__(self, mode="create", dut_form=None, lock_fields=None, system_model=None, parent=None):
|
||||
super().__init__(parent)
|
||||
self.mode = mode # "create" | "edit"
|
||||
self.dut_form = dut_form or {}
|
||||
self.lock_fields = set(lock_fields or [])
|
||||
self.system_model = system_model # 用于加载机台数据
|
||||
self.setWindowTitle("编辑试验样品详情" if self.mode == "edit" else "新建试验样品")
|
||||
self.setModal(True)
|
||||
self.resize(800, 480)
|
||||
|
||||
# 机台数据缓存
|
||||
self.machines = []
|
||||
self.current_machine = None
|
||||
|
||||
self._build_ui()
|
||||
self._load_machines() # 加载机台数据
|
||||
self._fill_form(self.dut_form)
|
||||
self._apply_lock()
|
||||
|
||||
def _build_ui(self):
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(20, 20, 20, 20)
|
||||
layout.setSpacing(12)
|
||||
|
||||
#title = QLabel("编辑试验样品详情" if self.mode == "edit" else "新建试验样品详情")
|
||||
#title.setObjectName("title")
|
||||
#title.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
|
||||
#layout.addWidget(title)
|
||||
|
||||
form = QFormLayout()
|
||||
form.setLabelAlignment(Qt.AlignRight)
|
||||
form.setFormAlignment(Qt.AlignTop)
|
||||
form.setHorizontalSpacing(16)
|
||||
form.setVerticalSpacing(12)
|
||||
|
||||
# 左右两列容器
|
||||
row = QHBoxLayout()
|
||||
left = QVBoxLayout()
|
||||
right = QVBoxLayout()
|
||||
|
||||
# 左列控件
|
||||
self.input_SN = QLineEdit()
|
||||
self.input_project = QLineEdit()
|
||||
self.input_testReq = QLineEdit()
|
||||
self.input_phase = QComboBox()
|
||||
self.input_phase.setEditable(True)
|
||||
self.input_phase.addItems(["A Sample", "B Sample", "C Sample", "Work Sample", "阶段1", "阶段2"]) # 示例项
|
||||
|
||||
# 右列控件 - 设备分配(二级选择)
|
||||
self.input_dtMachine = QComboBox() # 机台选择
|
||||
self.input_dtMachine.setEditable(False)
|
||||
self.input_dtMachine.addItem("", None) # 空选项
|
||||
self.input_dtMachine.currentIndexChanged.connect(self._on_machine_changed)
|
||||
|
||||
self.input_station = QComboBox() # 通道选择
|
||||
self.input_station.setEditable(False)
|
||||
self.input_station.addItem("", None) # 空选项
|
||||
|
||||
self.input_weeks = QLineEdit()
|
||||
self.input_workOrder = QLineEdit()
|
||||
self.input_inspector = QLineEdit()
|
||||
|
||||
# 说明
|
||||
self.input_description = QTextEdit()
|
||||
self.input_description.setPlaceholderText("请输入内容")
|
||||
|
||||
# 左列布局
|
||||
left_form = QFormLayout()
|
||||
left_form.setLabelAlignment(Qt.AlignRight)
|
||||
left_form.addRow("* 产品序列号", self.input_SN)
|
||||
left_form.addRow("项目代码", self.input_project)
|
||||
left_form.addRow("项目方案", self.input_testReq)
|
||||
left_form.addRow("项目阶段", self.input_phase)
|
||||
left.addLayout(left_form)
|
||||
|
||||
# 右列布局
|
||||
right_form = QFormLayout()
|
||||
right_form.setLabelAlignment(Qt.AlignRight)
|
||||
right_form.addRow("机台选择", self.input_dtMachine)
|
||||
right_form.addRow("通道选择", self.input_station)
|
||||
right_form.addRow("测试周次", self.input_weeks)
|
||||
right_form.addRow("工单名称", self.input_workOrder)
|
||||
right_form.addRow("测试人员", self.input_inspector)
|
||||
right.addLayout(right_form)
|
||||
|
||||
row.addLayout(left, 1)
|
||||
row.addLayout(right, 1)
|
||||
layout.addLayout(row)
|
||||
|
||||
# 说明一行单独处理
|
||||
desc_form = QFormLayout()
|
||||
desc_form.setLabelAlignment(Qt.AlignRight)
|
||||
desc_form.addRow("说明", self.input_description)
|
||||
layout.addLayout(desc_form)
|
||||
|
||||
# 底部按钮
|
||||
btn_row = QHBoxLayout()
|
||||
btn_row.addStretch()
|
||||
self.btn_submit = QPushButton("修改" if self.mode == "edit" else "保存")
|
||||
self.btn_close = QPushButton("关闭")
|
||||
btn_row.addWidget(self.btn_submit)
|
||||
btn_row.addWidget(self.btn_close)
|
||||
layout.addLayout(btn_row)
|
||||
|
||||
self.btn_submit.clicked.connect(self.accept)
|
||||
self.btn_close.clicked.connect(self.reject)
|
||||
|
||||
def _load_machines(self):
|
||||
"""加载机台数据"""
|
||||
if not self.system_model:
|
||||
return
|
||||
|
||||
try:
|
||||
self.machines = self.system_model.load_machines()
|
||||
|
||||
# 填充机台下拉框
|
||||
self.input_dtMachine.clear()
|
||||
self.input_dtMachine.addItem("", None) # 空选项
|
||||
|
||||
for machine in self.machines:
|
||||
sn = machine.get("SN", "")
|
||||
label = machine.get("label", "")
|
||||
display = f"{sn} - {label}" if label else sn
|
||||
self.input_dtMachine.addItem(display, machine)
|
||||
except Exception as e:
|
||||
print(f"加载机台数据失败: {e}")
|
||||
|
||||
def _on_machine_changed(self, index):
|
||||
"""机台选择变化时更新通道列表"""
|
||||
self.input_station.clear()
|
||||
self.input_station.addItem("", None) # 空选项
|
||||
|
||||
machine = self.input_dtMachine.currentData()
|
||||
if not machine:
|
||||
return
|
||||
|
||||
self.current_machine = machine
|
||||
|
||||
# 添加有效的通道(station1-4)
|
||||
for i in range(1, 5):
|
||||
station_key = f"station{i}"
|
||||
status_key = f"status{i}"
|
||||
try:
|
||||
# 安全获取通道名称,处理None和空值
|
||||
station_name = machine.get(station_key)
|
||||
if station_name is None:
|
||||
continue
|
||||
|
||||
station_name = str(station_name).strip()
|
||||
station_status = machine.get(status_key, "")
|
||||
|
||||
# 过滤掉空值和 NA/N/A 的通道
|
||||
if station_name and station_name.upper() not in ['NA', 'N/A']:
|
||||
display = f"{i:02d} - {station_name}"
|
||||
if station_status:
|
||||
display += f" ({station_status})"
|
||||
self.input_station.addItem(display, f"{i:02d}")
|
||||
except Exception as e:
|
||||
print(f"加载通道数据失败: {e}")
|
||||
|
||||
def _fill_form(self, f):
|
||||
# 将已有数据填充到控件
|
||||
self.input_SN.setText(str(f.get("SN", "")))
|
||||
self.input_project.setText(str(f.get("project", "")))
|
||||
self.input_testReq.setText(str(f.get("testReq", "")))
|
||||
phase_val = str(f.get("phase", ""))
|
||||
if phase_val:
|
||||
idx = self.input_phase.findText(phase_val)
|
||||
if idx >= 0:
|
||||
self.input_phase.setCurrentIndex(idx)
|
||||
else:
|
||||
self.input_phase.setEditText(phase_val)
|
||||
|
||||
# 设备分配:使用 Model 解析后的 dtMachine 和 station 字段
|
||||
dtm = f.get("dtMachine", "").strip()
|
||||
station = f.get("station", "").strip()
|
||||
|
||||
# 选中机台
|
||||
if dtm:
|
||||
for i in range(self.input_dtMachine.count()):
|
||||
machine = self.input_dtMachine.itemData(i)
|
||||
if machine and machine.get("SN") == dtm:
|
||||
self.input_dtMachine.setCurrentIndex(i)
|
||||
break
|
||||
|
||||
# 选中通道(需要在机台选中后)
|
||||
if station:
|
||||
for i in range(self.input_station.count()):
|
||||
station_num = self.input_station.itemData(i)
|
||||
if station_num == station:
|
||||
self.input_station.setCurrentIndex(i)
|
||||
break
|
||||
|
||||
self.input_weeks.setText(str(f.get("weeks", "")))
|
||||
self.input_workOrder.setText(str(f.get("workOrder", "")))
|
||||
self.input_inspector.setText(str(f.get("inspector", "")))
|
||||
self.input_description.setPlainText(str(f.get("description", "")))
|
||||
|
||||
def _apply_lock(self):
|
||||
# 根据锁定字段禁用编辑(默认在编辑模式锁定 SN)
|
||||
defaults = {"SN"} if self.mode == "edit" else set()
|
||||
locked = defaults | self.lock_fields
|
||||
if "SN" in locked:
|
||||
self.input_SN.setDisabled(True)
|
||||
# 注意:设备分配在编辑模式下是可以更改的
|
||||
|
||||
def get_form_dict(self):
|
||||
# 以 dut_form 的结构返回数据
|
||||
dut_form = {
|
||||
"SN": self.input_SN.text().strip(),
|
||||
"project": self.input_project.text().strip(),
|
||||
"testReq": self.input_testReq.text().strip(),
|
||||
"phase": self.input_phase.currentText().strip(),
|
||||
"weeks": int(self.input_weeks.text() or 0),
|
||||
"workOrder": self.input_workOrder.text().strip(),
|
||||
"inspector": self.input_inspector.text().strip(),
|
||||
"description": self.input_description.toPlainText().strip(),
|
||||
}
|
||||
|
||||
# 设备分配:从二级选择中获取 dtMachine 和 station
|
||||
# Model 会自动将这两个字段合成为 JSON 字符串存入 stationAssigned
|
||||
machine = self.input_dtMachine.currentData()
|
||||
station_num = self.input_station.currentData()
|
||||
|
||||
if machine and station_num:
|
||||
dut_form["dtMachine"] = machine.get("SN", "")
|
||||
dut_form["station"] = station_num
|
||||
else:
|
||||
dut_form["dtMachine"] = ""
|
||||
dut_form["station"] = ""
|
||||
|
||||
# 保留可能存在的 id 等字段
|
||||
if "id" in self.dut_form:
|
||||
dut_form["id"] = self.dut_form["id"]
|
||||
return dut_form
|
||||
Reference in New Issue
Block a user