from PySide6.QtWidgets import ( QMainWindow, QWidget, QLabel, QGridLayout, QVBoxLayout, QHBoxLayout, QTableWidget, QTableWidgetItem, QHeaderView, QFrame, QSplitter, QPushButton, QLineEdit, QAbstractItemView, QComboBox, QSizePolicy, QTextEdit ) from PySide6.QtGui import QFont, QAction, QBrush, QColor from PySide6.QtCore import Qt, QDateTime, QTimer class MainWindowUI(QMainWindow): # 定义字段映射为类属性,方便外部引用 FIELD_MAPPING = { "库房": "lib", "客户": "customerexp", "规格": "size", "材质": "cz", "种类": "type_name", "钢厂": "cd", "炉号": "luno", "轴型": "zx_name", "标签": "template_name", "打印材质": "cz", "底托类型": "spack_type", "强度范围": "qx", "强度": "qd", "延伸要求": "ysl", "线材类型": "jz", "包装方式": "bzfs", "轴重要求": "zzyq", "线径公差": "xj", "备注": "remarks_hb" } def __init__(self,username): super().__init__() self.username = username self.setWindowTitle(f"腾智微丝产线包装系统") self.resize(1200, 800) self.init_ui() def init_ui(self): # 设置字体 self.title_font = QFont("微软雅黑", 20, QFont.Bold) self.second_title_font = QFont("微软雅黑", 14, QFont.Bold) self.normal_font = QFont("微软雅黑", 12) self.small_font = QFont("微软雅黑", 9) # 创建菜单栏 self.create_menu() # 创建中央部件 self.central_widget = QWidget() self.setCentralWidget(self.central_widget) # 创建主布局 - 水平分割 self.main_layout = QHBoxLayout(self.central_widget) self.main_layout.setContentsMargins(5, 5, 5, 5) self.main_layout.setSpacing(5) # 创建左侧面板 self.left_panel = QWidget() self.left_layout = QVBoxLayout(self.left_panel) self.left_layout.setContentsMargins(0, 0, 0, 0) self.left_layout.setSpacing(5) self.create_left_panel() # 创建右侧面板 self.right_panel = QWidget() self.right_layout = QVBoxLayout(self.right_panel) self.right_layout.setContentsMargins(0, 0, 0, 0) self.right_layout.setSpacing(5) self.create_right_panel() # 添加左右面板到主布局 self.main_layout.addWidget(self.left_panel, 1) # 左侧面板占比较小 self.main_layout.addWidget(self.right_panel, 2) # 右侧面板占比较大 def create_menu(self): # 创建菜单栏 self.menubar = self.menuBar() # 用户操作菜单 self.user_menu = self.menubar.addMenu("用户操作页") self.main_action = QAction("主页面", self) self.user_menu.addAction(self.main_action) # 系统设置菜单 self.system_menu = self.menubar.addMenu("系统设置") self.settings_action = QAction("设置页面", self) self.system_menu.addAction(self.settings_action) def create_left_panel(self): # 创建标题容器 self.title_container = QWidget() self.title_layout = QHBoxLayout(self.title_container) self.title_layout.setContentsMargins(10, 10, 10, 10) self.title_layout.setSpacing(10) # 创建用户名标签 self.username_label = QLabel(self.username) self.username_label.setFont(self.normal_font) self.username_label.setStyleSheet("color: #666666;") self.username_label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) # 创建主标题标签 self.title_label = QLabel("腾智微丝产线包装系统") self.title_label.setFont(self.title_font) # 较大的字体 self.title_label.setAlignment(Qt.AlignCenter) self.title_label.setStyleSheet("color: #1a237e;") # 创建时间标签 self.time_label = QLabel() self.time_label.setFont(self.normal_font) self.time_label.setStyleSheet("color: #666666;") self.time_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) # 创建定时器更新时间 self.timer = QTimer(self) self.timer.timeout.connect(self.update_time) self.timer.start(1000) # 每秒更新一次 self.update_time() # 立即更新一次时间 # 将标签添加到标题布局中 self.title_layout.addWidget(self.username_label, 1) self.title_layout.addWidget(self.title_label, 2) # 中间标题占据更多空间 self.title_layout.addWidget(self.time_label, 1) # 设置标题容器的样式 self.title_container.setStyleSheet("background-color: #f5f5f5; border-radius: 4px;") self.left_layout.addWidget(self.title_container) # 项目信息表格 - 使用QFrame包裹,添加边框 self.project_frame = QFrame() self.project_frame.setFrameShape(QFrame.StyledPanel) self.project_frame.setLineWidth(1) self.project_frame.setFixedHeight(150) # 调整这个值可以控制整体高度 self.project_layout = QVBoxLayout(self.project_frame) self.project_layout.setContentsMargins(5, 5, 5, 5) # 项目表格 self.project_table = QTableWidget(4, 4) self.project_table.setHorizontalHeaderLabels(["用电", "数量", "产量", "开机率"]) self.project_table.setVerticalHeaderLabels(["当日", "当月", "当年", "累计"]) #设置字体 self.project_table.setFont(self.normal_font) # 设置垂直表头宽度 self.project_table.verticalHeader().setFixedWidth(60) self.project_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.project_table.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) self.project_table.setEditTriggers(QTableWidget.NoEditTriggers) # 设置为不可编辑 self.project_layout.addWidget(self.project_table) self.left_layout.addWidget(self.project_frame) # 任务信息区域 - 使用QFrame包裹,添加边框 self.task_frame = QFrame() self.task_frame.setFrameShape(QFrame.StyledPanel) self.task_frame.setLineWidth(1) self.task_frame.setFixedHeight(180) self.task_layout = QVBoxLayout(self.task_frame) self.task_layout.setContentsMargins(8, 8, 8, 8) # 任务标签 self.task_label = QLabel("任务") self.task_label.setFont(self.normal_font) self.task_label.setAlignment(Qt.AlignLeft) self.task_label.setStyleSheet("font-weight: bold; color: #333333;") self.task_layout.addWidget(self.task_label) # 订单行 self.order_layout = QHBoxLayout() self.order_layout.setAlignment(Qt.AlignLeft) # 设置整个布局左对齐 self.order_label = QLabel("工程号") self.order_label.setFont(QFont("微软雅黑", 12, QFont.Bold)) self.order_label.setFixedHeight(30) self.order_label.setStyleSheet("padding: 0 5px; color: #333333;") self.order_edit = QLineEdit() self.order_edit.setFixedHeight(30) self.order_edit.setFixedWidth(150) self.order_edit.setReadOnly(False) self.order_edit.setFont(QFont("微软雅黑", 12)) self.order_edit.setText("") # 设置默认订单号 self.order_edit.setStyleSheet("background-color: #f9f9f9; border: 1px solid #cccccc; border-radius: 3px; padding: 2px 5px;") self.order_layout.addWidget(self.order_label) self.order_layout.addWidget(self.order_edit) self.order_layout.addStretch() # 添加弹性空间,将组件推到左侧 self.task_layout.addLayout(self.order_layout) # 任务表格 - 使用合并单元格实现一级二级标题 self.task_table = QTableWidget(3, 4) # 3行4列:一级标题行、二级标题行、数据行 self.task_table.setEditTriggers(QTableWidget.NoEditTriggers) # 设置为不可编辑 self.task_table.horizontalHeader().setVisible(False) self.task_table.verticalHeader().setVisible(False) self.task_table.setShowGrid(True) # 设置列宽均等 self.task_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 第一行:订单量和完成量 (一级标题) self.task_table.setSpan(0, 0, 1, 2) # 订单量跨2列 self.task_table.setSpan(0, 2, 1, 2) # 完成量跨2列 order_item = QTableWidgetItem("订单量") order_item.setTextAlignment(Qt.AlignCenter) order_item.setFont(self.normal_font) self.task_table.setItem(0, 0, order_item) completed_item = QTableWidgetItem("完成量") completed_item.setTextAlignment(Qt.AlignCenter) completed_item.setFont(self.normal_font) self.task_table.setItem(0, 2, completed_item) # 第二行:二级标题 headers = ["总生产数量", "总生产公斤", "已完成数量", "已完成公斤"] for col, header in enumerate(headers): item = QTableWidgetItem(header) item.setTextAlignment(Qt.AlignCenter) item.setFont(self.small_font) self.task_table.setItem(1, col, item) # 设置行高 self.task_table.setRowHeight(0, 30) # 一级标题行高 self.task_table.setRowHeight(1, 30) # 二级标题行高 self.task_table.setRowHeight(2, 30) # 数据行高 self.task_layout.addWidget(self.task_table) self.left_layout.addWidget(self.task_frame) # 上料区 - 使用QFrame包裹,添加边框 self.material_frame = QFrame() self.material_frame.setFrameShape(QFrame.StyledPanel) self.material_frame.setLineWidth(1) self.material_frame.setFixedHeight(380) # 保持上料区高度不变 self.material_frame.setStyleSheet("QFrame { background-color: #f8f8f8; }") self.material_layout = QHBoxLayout(self.material_frame) self.material_layout.setContentsMargins(0, 0, 0, 0) self.material_layout.setSpacing(0) # 上料区标签 self.material_label = QLabel("托盘入库") self.material_label.setFont(self.normal_font) self.material_label.setAlignment(Qt.AlignCenter) self.material_label.setFixedWidth(100) # 设置固定宽度 self.material_label.setStyleSheet("background-color: #e0e0e0; border-right: 1px solid #cccccc; font-weight: bold;") self.material_layout.addWidget(self.material_label) # 上料区内容 - 订单信息表格 self.material_content = QWidget() self.material_content.setStyleSheet("background-color: white;") self.material_content_layout = QVBoxLayout(self.material_content) self.material_content_layout.setContentsMargins(10, 10, 10, 10) # 移除滚动区域,直接使用表格 # 创建订单号输入框 self.order_info_layout = QHBoxLayout() self.order_no_label = QLabel("订单号:") self.order_no_label.setFont(self.normal_font) self.order_no_label.setFixedWidth(60) self.order_no_input = QLineEdit() self.order_no_input.setFont(self.normal_font) self.order_no_input.setReadOnly(True) self.order_no_input.setStyleSheet("background-color: #f5f5f5; border: 1px solid #cccccc; padding: 3px;") self.order_info_layout.addWidget(self.order_no_label) self.order_info_layout.addWidget(self.order_no_input) self.order_info_layout.addStretch() # 添加托盘完成按钮 self.tray_complete_button = QPushButton("托盘完成") self.tray_complete_button.setFont(self.normal_font) self.tray_complete_button.setStyleSheet(""" QPushButton { padding: 5px 8px; background-color: #e8f5e9; border: 1px solid #4caf50; } QPushButton:hover { background-color: #c8e6c9; } """) self.order_info_layout.addWidget(self.tray_complete_button) self.material_content_layout.addLayout(self.order_info_layout) # 创建信息表格 - 使用QTableWidget实现 self.info_table = QTableWidget() # 计算需要的行数:19个字段,每行2个字段,最后两行是备注(跨列) # 前18个字段需要9行,备注占用2行,总共11行 self.info_table.setRowCount(11) # 9行常规字段 + 2行备注 self.info_table.setColumnCount(4) # 4列:标签1, 值1, 标签2, 值2 self.info_table.setShowGrid(True) # 显示网格线 self.info_table.horizontalHeader().setVisible(False) # 隐藏水平表头 self.info_table.verticalHeader().setVisible(False) # 隐藏垂直表头 # 设置表格样式 self.info_table.setStyleSheet(""" QTableWidget { border-top: 1px solid #cccccc; border-left: 1px solid #cccccc; border-right: none; border-bottom: none; gridline-color: #cccccc; } """) # 定义字段和对应的数据键 field_mapping = self.FIELD_MAPPING # 创建标签和值的字典,用于后续更新 self.info_labels = {} self.info_values = {} # 填充表格内容 row = 0 col = 0 for i, field_name in enumerate(field_mapping.keys()): if field_name == "备注": # 备注行特殊处理 # 创建标签 label = QLabel("备注") label.setFont(self.normal_font) label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) label.setStyleSheet("background-color: #FAFAFA; padding: 5px;") # 创建值(改为QTextEdit) value = QTextEdit("") value.setFont(self.normal_font) value.setStyleSheet("background-color: white; padding: 5px; border: 1px solid #cccccc;") value.setFixedHeight(70) # 增加高度为两行 value.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) value.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) value.setFrameStyle(QFrame.NoFrame) value.setLineWrapMode(QTextEdit.WidgetWidth) # 允许自动换行 value.setContentsMargins(0, 0, 0, 0) value.setAcceptRichText(False) value.setTabChangesFocus(True) # 保存引用 self.info_labels["备注"] = label self.info_values["备注"] = value # 添加到表格,占用两行 self.info_table.setCellWidget(row, 0, label) self.info_table.setCellWidget(row, 1, value) self.info_table.setSpan(row, 0, 2, 1) # 标签跨越2行1列 self.info_table.setSpan(row, 1, 2, 3) # 值跨越2行3列 else: # 创建标签 label = QLabel(field_name) label.setFont(self.normal_font) label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) label.setStyleSheet("background-color: #FAFAFA; padding: 5px;") # 根据字段类型创建不同的值组件 if field_name == "库房": # 库房字段使用QComboBox,完全复刻托盘号组件的配置 value = QComboBox() value.setFixedHeight(35) value.setStyleSheet("QComboBox { border: 1px solid #cccccc; padding: 3px; background-color: white; } QComboBox::drop-down { border: none; width: 20px; }") value.setFont(QFont("微软雅黑", 12)) value.setEditable(False) # 设置为不可编辑,确保是纯下拉选择 value.setInsertPolicy(QComboBox.NoInsert) # 不自动插入用户输入到列表中 value.setMaxVisibleItems(10) # 设置下拉框最多显示10个项目 # 添加默认选项 value.addItem("成品库") value.addItem("退回仓") value.addItem("散装库") value.addItem("不合格库(线材)") value.addItem("废丝库") value.setCurrentIndex(0) # 默认选择第一个 elif field_name == "线材类型": # 线材类型字段使用QComboBox,与库房组件配置相同 value = QComboBox() value.setFixedHeight(35) value.setStyleSheet("QComboBox { border: 1px solid #cccccc; padding: 3px; background-color: white; } QComboBox::drop-down { border: none; width: 20px; }") value.setFont(QFont("微软雅黑", 12)) value.setEditable(False) # 设置为不可编辑,确保是纯下拉选择 value.setInsertPolicy(QComboBox.NoInsert) # 不自动插入用户输入到列表中 value.setMaxVisibleItems(10) # 设置下拉框最多显示10个项目 # 添加默认选项(后续会从API动态加载) value.addItem("请选择") value.setCurrentIndex(0) # 默认选择第一个 elif field_name == "包装方式": # 包装方式字段使用QLineEdit,与其他字段保持一致 value = QLineEdit("") value.setFont(self.normal_font) value.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) value.setStyleSheet("background-color: white; padding: 5px; border: 1px solid #cccccc;") else: # 其他字段使用QLineEdit value = QLineEdit("") value.setFont(self.normal_font) value.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) value.setStyleSheet("background-color: white; padding: 5px; border: 1px solid #cccccc;") value.setFrame(False) value.setContentsMargins(0, 0, 0, 0) value.setFixedHeight(35) # 保存引用 self.info_labels[field_name] = label self.info_values[field_name] = value # 添加到表格 self.info_table.setCellWidget(row, col * 2, label) self.info_table.setCellWidget(row, col * 2 + 1, value) # 更新行列索引 col += 1 if col >= 2: # 每行两组数据 col = 0 row += 1 # 设置行高 for i in range(self.info_table.rowCount()): if i == 9: # 备注行(第10行,索引为9) self.info_table.setRowHeight(i, 35) # 备注行第一行高度 self.info_table.setRowHeight(i + 1, 35) # 备注行第二行高度 break else: self.info_table.setRowHeight(i, 35) # 普通行高度 # 设置表格自适应宽度 self.info_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 设置表格填充整个容器 self.info_table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # 直接添加表格到主布局 self.material_content_layout.addWidget(self.info_table) self.material_layout.addWidget(self.material_content) self.left_layout.addWidget(self.material_frame) # 托盘号区域 - 使用QFrame包裹,添加边框 self.tray_frame = QFrame() self.tray_frame.setFrameShape(QFrame.StyledPanel) self.tray_frame.setLineWidth(1) # 移除固定高度,让托盘号的高度自适应其内容 self.tray_frame.setFixedHeight(40) # 进一步减小高度,刚好容纳控件 self.tray_frame.setStyleSheet("QFrame { background-color: #f8f8f8; }") self.tray_layout = QHBoxLayout(self.tray_frame) self.tray_layout.setContentsMargins(0, 0, 0, 0) # 移除内边距,确保没有上下边界 # 移除所有边距 self.tray_layout.setSpacing(0) # 移除所有间距 self.tray_label = QLabel("托盘号") self.tray_label.setFont(self.normal_font) self.tray_label.setAlignment(Qt.AlignCenter) self.tray_label.setFixedWidth(100) # 设置固定宽度 self.tray_label.setStyleSheet("background-color: #e0e0e0; border-right: 1px solid #cccccc; font-weight: bold;") self.tray_layout.addWidget(self.tray_label) self.tray_edit = QComboBox() self.tray_edit.setFixedHeight(40) # 设置固定高度与父容器相同 self.tray_edit.setStyleSheet("QComboBox { border: none; padding: 0px 10px; background-color: white; } QComboBox::drop-down { border: none; width: 20px; }") self.tray_edit.setFont(QFont("微软雅黑", 12)) self.tray_edit.setEditable(True) # 允许手动输入 self.tray_edit.setInsertPolicy(QComboBox.NoInsert) # 不自动插入用户输入到列表中 self.tray_edit.setMaxVisibleItems(10) # 设置下拉框最多显示10个项目 self.tray_edit.completer().setCaseSensitivity(Qt.CaseInsensitive) # 设置补全不区分大小写 self.tray_edit.completer().setFilterMode(Qt.MatchContains) # 设置模糊匹配模式 # 允许清空选择 self.tray_edit.setCurrentText("") self.tray_layout.addWidget(self.tray_edit) self.left_layout.addWidget(self.tray_frame) # 下料区 - 使用QFrame包裹,添加边框 self.output_frame = QFrame() self.output_frame.setFrameShape(QFrame.StyledPanel) self.output_frame.setLineWidth(1) self.output_frame.setFixedHeight(100) # 压缩下料区域的高度,从原来的150减少到100 self.output_frame.setStyleSheet("QFrame { background-color: #f8f8f8; }") self.output_layout = QHBoxLayout(self.output_frame) self.output_layout.setContentsMargins(0, 0, 0, 0) self.output_layout.setSpacing(0) # 下料区标签 self.output_label = QLabel("下料") self.output_label.setFont(self.normal_font) self.output_label.setAlignment(Qt.AlignCenter) self.output_label.setFixedWidth(100) # 设置固定宽度 self.output_label.setStyleSheet("background-color: #e0e0e0; border-right: 1px solid #cccccc; font-weight: bold;") self.output_layout.addWidget(self.output_label) # 下料区内容 - 这里可以添加更多控件 self.output_content = QWidget() self.output_content.setStyleSheet("background-color: white;") self.output_content_layout = QVBoxLayout(self.output_content) self.output_content_layout.setContentsMargins(5, 5, 5, 5) # 减小内部边距 self.output_layout.addWidget(self.output_content) self.left_layout.addWidget(self.output_frame) # 产线控制区 - 使用QFrame包裹,添加边框 self.control_frame = QFrame() self.control_frame.setFrameShape(QFrame.StyledPanel) self.control_frame.setLineWidth(1) self.control_layout = QHBoxLayout(self.control_frame) self.control_layout.setContentsMargins(0, 0, 0, 0) self.control_layout.setSpacing(0) self.control_label = QLabel("产线") self.control_label.setFont(self.normal_font) self.control_label.setAlignment(Qt.AlignCenter) self.control_label.setFixedWidth(100) # 设置固定宽度 self.control_label.setStyleSheet("background-color: #e0e0e0; border-right: 1px solid #cccccc; font-weight: bold;") self.control_layout.addWidget(self.control_label) # 按钮容器 self.button_container = QWidget() self.button_layout = QGridLayout(self.button_container) self.button_layout.setContentsMargins(10, 10, 10, 10) self.button_layout.setSpacing(10) # 增加按钮间距 # 创建按钮并设置样式 button_style = """ QPushButton { padding: 8px 16px; font-weight: bold; border-radius: 4px; } """ self.input_button = QPushButton("上料") self.input_button.setFont(self.normal_font) self.input_button.setStyleSheet(button_style + "background-color: #e3f2fd; border: 1px solid #2196f3;") self.output_button = QPushButton("下料") self.output_button.setFont(self.normal_font) self.output_button.setStyleSheet(button_style + "background-color: #fff8e1; border: 1px solid #ffc107;") self.start_button = QPushButton("开始") self.start_button.setFont(self.normal_font) self.start_button.setStyleSheet(button_style + "background-color: #e8f5e9; border: 1px solid #4caf50;") self.stop_button = QPushButton("暂停") self.stop_button.setFont(self.normal_font) self.stop_button.setStyleSheet(button_style + "background-color: #ffebee; border: 1px solid #f44336;") self.report_button = QPushButton("报表") self.report_button.setFont(self.normal_font) self.report_button.setStyleSheet(button_style + "background-color: #e0e0e0; border: 1px solid #cccccc;") # 使用网格布局排列按钮 self.button_layout.addWidget(self.input_button, 0, 0) self.button_layout.addWidget(self.output_button, 0, 1) self.button_layout.addWidget(self.start_button, 0, 2) self.button_layout.addWidget(self.stop_button, 0, 3) self.button_layout.addWidget(self.report_button, 0, 4) self.control_layout.addWidget(self.button_container) self.left_layout.addWidget(self.control_frame) # 添加弹性空间,确保控件紧凑排列在顶部 self.left_layout.addStretch() def create_right_panel(self): # 创建右侧整体框架 self.right_frame = QFrame() self.right_frame.setFrameShape(QFrame.NoFrame) # 移除框架边框 self.right_frame.setLineWidth(0) self.right_layout.addWidget(self.right_frame) # 右侧整体使用垂直布局,不设置边距 self.right_frame_layout = QVBoxLayout(self.right_frame) self.right_frame_layout.setContentsMargins(0, 0, 0, 0) self.right_frame_layout.setSpacing(0) # 创建一个垂直分割器,用于控制两个表格的高度比例 self.right_splitter = QSplitter(Qt.Vertical) # 创建微丝产线表格的容器 self.process_container = QWidget() self.process_container_layout = QVBoxLayout(self.process_container) self.process_container_layout.setContentsMargins(0, 0, 0, 0) self.process_container_layout.setSpacing(0) # 创建包装记录表格的容器 self.record_container = QWidget() self.record_container_layout = QVBoxLayout(self.record_container) self.record_container_layout.setContentsMargins(0, 0, 0, 0) self.record_container_layout.setSpacing(0) # 创建微丝产线表格 self.create_process_table() self.process_container_layout.addWidget(self.process_frame) # 创建包装记录表格 self.create_record_table() self.record_container_layout.addWidget(self.record_frame) # 将两个容器添加到分割器中 self.right_splitter.addWidget(self.process_container) self.right_splitter.addWidget(self.record_container) # 设置初始大小比例:微丝产线占1/3,包装记录占2/3 self.right_splitter.setSizes([100, 200]) # 比例为1:2 # 将分割器添加到右侧布局 self.right_frame_layout.addWidget(self.right_splitter) # 添加一个通用的表格样式设置方法 def setup_table_common(self, table, hide_headers=True): """设置表格的通用样式和属性 Args: table: 要设置的QTableWidget对象 hide_headers: 是否隐藏默认的表头 """ # 设置为不可编辑 table.setEditTriggers(QAbstractItemView.NoEditTriggers) # 隐藏默认表头 if hide_headers: table.horizontalHeader().setVisible(False) table.verticalHeader().setVisible(False) # 显示网格线 table.setShowGrid(True) # 移除外边框 table.setFrameShape(QFrame.NoFrame) # 设置表格样式 table.setStyleSheet(""" QTableWidget { gridline-color: #dddddd; border: none; background-color: white; } QTableWidget::item { border: none; padding: 3px; } QTableWidget::item:selected { background-color: #e0e0ff; color: black; } """) # 允许用户调整列宽 table.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive) table.horizontalHeader().setStretchLastSection(True) return table # 添加一个通用的表头项创建方法 def create_header_item(self, text, font=None, alignment=Qt.AlignCenter, bg_color="#f8f8f8"): """创建表头单元格项 Args: text: 表头文本 font: 字体,默认为None(使用self.normal_font) alignment: 对齐方式 bg_color: 背景色 Returns: QTableWidgetItem: 创建的表头项 """ item = QTableWidgetItem(text) item.setTextAlignment(alignment) item.setFont(font or self.normal_font) item.setBackground(QBrush(QColor(bg_color))) return item def create_process_table(self): """创建微丝产线表格,包含上料、检验、包装部分""" # 创建微丝产线框架 self.process_frame = QFrame() self.process_frame.setFrameShape(QFrame.NoFrame) # 移除边框 self.process_frame.setLineWidth(0) self.process_frame.setStyleSheet("QFrame { background-color: #f5f5f5; }") # 与其他标题背景色一致 self.process_layout = QVBoxLayout(self.process_frame) self.process_layout.setContentsMargins(0, 0, 0, 0) self.process_layout.setSpacing(0) # 微丝产线标题 self.process_title = QLabel("微丝产线") self.process_title.setFont(self.second_title_font) self.process_title.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.process_title.setFixedHeight(40) self.process_title.setStyleSheet("background-color: #f5f5f5; padding: 5px;") # 移除底部边框 self.process_layout.addWidget(self.process_title) # 创建表格内容区域 self.process_content = QWidget() self.process_content_layout = QVBoxLayout(self.process_content) self.process_content_layout.setContentsMargins(0, 0, 0, 0) self.process_content_layout.setSpacing(0) # 创建表格 - 支持动态配置检验列数 self.inspection_columns = 1 # 默认至少显示1列 # 默认检验标题,实际运行时将通过InspectionConfigManager获取 self.inspection_headers = ["检验项"] total_columns = 2 + self.inspection_columns + 2 # 上料2列 + 检验N列 + 包装2列 self.process_table = QTableWidget(8, total_columns) # 8行:1行标题区域 + 1行列标题 + 6行数据 # 应用通用表格设置 self.setup_table_common(self.process_table) # 设置行高 self.process_table.setRowHeight(0, 30) # 标题区域行高 self.process_table.setRowHeight(1, 30) # 列标题行高 # 设置数据行的行高 for row in range(2, 8): # 工序行 self.process_table.setRowHeight(row, 35) # 设置列宽 self.set_process_table_column_widths() # 创建表头 - 合并单元格 self.create_process_table_headers() # 添加表格到布局 self.process_content_layout.addWidget(self.process_table) self.process_layout.addWidget(self.process_content) def create_record_table(self): """创建包装记录表格""" # 创建包装记录框架 self.record_frame = QFrame() self.record_frame.setFrameShape(QFrame.NoFrame) # 移除边框 self.record_frame.setLineWidth(0) self.record_frame.setStyleSheet("QFrame { background-color: #f5f5f5; }") # 与其他标题背景色一致 self.record_layout = QVBoxLayout(self.record_frame) self.record_layout.setContentsMargins(0, 0, 0, 0) self.record_layout.setSpacing(0) # 包装记录标题 self.record_title = QLabel("包装记录") self.record_title.setFont(self.second_title_font) self.record_title.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.record_title.setFixedHeight(40) self.record_title.setStyleSheet("background-color: #f5f5f5; padding: 5px;") # 移除底部边框 # 创建标题容器,用于水平布局标题和按钮 self.record_title_container = QWidget() self.record_title_layout = QHBoxLayout(self.record_title_container) self.record_title_layout.setContentsMargins(5, 0, 5, 0) self.record_title_layout.setSpacing(10) # 添加标题到布局 self.record_title_layout.addWidget(self.record_title) # 添加弹性空间,确保标题居左 self.record_title_layout.addStretch() # 添加弹性空间 # 将标题容器添加到记录布局 self.record_layout.addWidget(self.record_title_container) # 创建表格 self.record_table = QTableWidget(13, 10) # 13行10列:序号、订单、工程号、品名、规格、托号、轴包装号、重量、净重、完成时间 # 应用通用表格设置但保留表头 self.setup_table_common(self.record_table, hide_headers=False) # 设置列标题 record_headers = ["序号", "订单", "工程号", "品名", "规格", "托号", "轴包装号", "毛重", "净重", "完成时间"] self.record_table.setHorizontalHeaderLabels(record_headers) # 设置表头样式 self.record_table.horizontalHeader().setStyleSheet(""" QHeaderView::section { background-color: #f8f8f8; padding: 4px; border: 1px solid #dddddd; font-weight: bold; } """) # 设置行高 self.record_table.setRowHeight(12, 35) # 合计行高 # 设置数据行的行高 for row in range(0, 12): # 记录行 self.record_table.setRowHeight(row, 35) # 设置列宽 column_widths = [60, 170, 170, 120, 120, 150, 100, 100, 100, 160] for col, width in enumerate(column_widths): self.record_table.setColumnWidth(col, width) self.record_table.horizontalHeader().resizeSection(col, width) # 添加表格到布局 self.record_layout.addWidget(self.record_table) # 添加一个通用的单元格创建方法 def create_cell_item(self, text, alignment=Qt.AlignCenter): """创建表格单元格项 Args: text: 单元格文本 alignment: 对齐方式 Returns: QTableWidgetItem: 创建的单元格项 """ item = QTableWidgetItem(str(text)) item.setTextAlignment(alignment) return item def set_inspection_columns(self, columns, headers=None): """设置检验列数和标题 Args: columns: 检验列数量 headers: 检验列标题列表,如果为None则使用默认标题 """ # 确保列数在1-6之间 columns = max(1, min(6, columns)) # 保存旧的列数 old_column_count = self.process_table.columnCount() # 清除表头行的所有项目 if old_column_count > 0: for c_idx in range(old_column_count): # 第0行 - 主标题 item_r0 = self.process_table.takeItem(0, c_idx) if item_r0: del item_r0 # 第1行 - 子标题 item_r1 = self.process_table.takeItem(1, c_idx) if item_r1: del item_r1 # 清除所有单元格合并 for row in range(2): for col in range(old_column_count): try: self.process_table.setSpan(row, col, 1, 1) except: pass # 忽略错误,可能有些单元格没有合并 # 更新检验列数 self.inspection_columns = columns # 更新检验标题 if headers is not None and len(headers) >= columns: self.inspection_headers = headers[:columns] # 只使用前N个标题 elif len(self.inspection_headers) < columns: # 如果当前标题不足,扩展标题列表 current_len = len(self.inspection_headers) for i in range(current_len, columns): self.inspection_headers.append(f"检验项{i+1}") # 截断多余的标题 if len(self.inspection_headers) > columns: self.inspection_headers = self.inspection_headers[:columns] # 计算总列数 total_columns = 2 + self.inspection_columns + 3 # 上料2列 + 检验N列 + 包装3列 self.process_table.setColumnCount(total_columns) # 重新设置列宽 self.set_process_table_column_widths() # 重新创建表头 self.create_process_table_headers() def create_process_table_headers(self): """创建微丝产线表格的表头,实现合并单元格""" # 第一行:上料、检验、包装标题区域 # 上料区域(2列) self.process_table.setSpan(0, 0, 1, 2) self.process_table.setItem(0, 0, self.create_header_item("上料")) # 检验区域(动态列数) self.process_table.setSpan(0, 2, 1, self.inspection_columns) self.process_table.setItem(0, 2, self.create_header_item("检验")) # 包装区域(3列) packaging_start_col = 2 + self.inspection_columns self.process_table.setSpan(0, packaging_start_col, 1, 3) self.process_table.setItem(0, packaging_start_col, self.create_header_item("包装")) # 第二行:列标题 # 上料区域列标题 material_headers = ["序号", "工程号"] for col, header in enumerate(material_headers): self.process_table.setItem(1, col, self.create_header_item(header)) # 检验区域列标题 - 可动态配置 for i in range(self.inspection_columns): header_text = "" if i < len(self.inspection_headers): header_text = self.inspection_headers[i] else: header_text = f"检验项{i+1}" # 如果没有定义足够的标题,使用默认标题 self.process_table.setItem(1, 2 + i, self.create_header_item(header_text)) # 包装区域列标题 packaging_headers = ["贴标", "毛重", "净重"] for i, header in enumerate(packaging_headers): self.process_table.setItem(1, packaging_start_col + i, self.create_header_item(header)) def set_process_table_column_widths(self): """设置微丝产线表格的列宽 - 支持动态配置检验列""" # 上料区域列宽 self.process_table.setColumnWidth(0, 70) # 序号 self.process_table.setColumnWidth(1, 190) # 工程号 # 检验区域列宽 for i in range(self.inspection_columns): self.process_table.setColumnWidth(2 + i, 140) # 检验列 # 包装区域列宽 packaging_start_col = 2 + self.inspection_columns self.process_table.setColumnWidth(packaging_start_col, 140) # 贴标 self.process_table.setColumnWidth(packaging_start_col + 1, 140) # 毛重 self.process_table.setColumnWidth(packaging_start_col + 2, 140) # 净重 def update_time(self): current_time = QDateTime.currentDateTime().toString('yyyy-MM-dd hh:mm:ss') self.time_label.setText(current_time)