From ca97662db67ad25ed85f534a5261c0cf11fbb458 Mon Sep 17 00:00:00 2001 From: zhu-mengmeng <15588200382@163.com> Date: Sun, 8 Jun 2025 01:24:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=8E=B7=E5=8F=96=E6=9C=AA?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=A3=80=E9=AA=8C=E6=95=B0=E6=8D=AE=E7=9A=84?= =?UTF-8?q?=E6=96=B9=E6=B3=95=EF=BC=8C=E4=BC=98=E5=8C=96=E4=B8=BB=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E4=BB=A5=E5=8A=A0=E8=BD=BD=E5=B9=B6=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E6=9C=AA=E5=AE=8C=E6=88=90=E7=9A=84=E6=A3=80=E9=AA=8C=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=EF=BC=9B=E5=AE=9E=E7=8E=B0=E8=A1=A8=E6=A0=BC=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E8=8F=9C=E5=8D=95=E5=8A=9F=E8=83=BD=E4=BB=A5?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E6=95=B0=E6=8D=AE=E5=BA=93=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dao/inspection_dao.py | 41 +++- db/jtDB.db | Bin 16384 -> 28672 bytes ui/main_window_ui.py | 41 +--- widgets/main_window.py | 474 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 510 insertions(+), 46 deletions(-) diff --git a/dao/inspection_dao.py b/dao/inspection_dao.py index 8ed46cb..11dba35 100644 --- a/dao/inspection_dao.py +++ b/dao/inspection_dao.py @@ -281,7 +281,46 @@ class InspectionDAO: self.db.rollback_transaction() logging.error(f"保存检验数据失败: {str(e)}") return False - + def get_inspection_data_unfinished(self): + """获取未完成的检验数据 + + Returns: + list: 未完成的检验数据列表 + """ + try: + sql = """ + SELECT d.id, d.order_id, d.position, d.config_id, d.value, d.status, d.remark, + c.name, c.display_name, c.data_type, c.unit + FROM inspection_data d + JOIN inspection_config c ON d.config_id = c.id + WHERE d.is_deleted = FALSE + AND order_id IN (SELECT distinct order_id FROM inspection_data WHERE status != 'pass') + ORDER BY d.order_id, d.position + """ + self.db.cursor.execute(sql) + results = self.db.cursor.fetchall() + + data_list = [] + for row in results: + data = { + 'id': row[0], + 'order_id': row[1], + 'position': row[2], + 'config_id': row[3], + 'value': row[4], + 'status': row[5], + 'remark': row[6], + 'name': row[7], + 'display_name': row[8], + 'data_type': row[9], + 'unit': row[10] + } + data_list.append(data) + + return data_list + except Exception as e: + logging.error(f"获取未完成的检验数据失败: {str(e)}") + return [] def get_inspection_data_by_order(self, order_id): """根据工程号获取检验数据 diff --git a/db/jtDB.db b/db/jtDB.db index ee2c5b8d0fad0c571b469f1ab893c3bb4a11593b..bce2c99346ee473a27f19e5ee6ee50b9bc95420d 100644 GIT binary patch literal 28672 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 delta 84 zcmZp8z}V2hI6+#FiGhKE1&CpQaiWf~FcX7bSvN2L4+dsFK?c5L{_}i-n*{~t^KKU8 g`>e>u$p4*z|NCY^g{S-z12{O@8JR^nON&#B0H)azDF6Tf diff --git a/ui/main_window_ui.py b/ui/main_window_ui.py index 9168b6a..98b8ead 100644 --- a/ui/main_window_ui.py +++ b/ui/main_window_ui.py @@ -653,43 +653,4 @@ class MainWindowUI(QMainWindow): # 包装区域列宽 packaging_start_col = 2 + self.inspection_columns self.process_table.setColumnWidth(packaging_start_col, 140) # 贴标 - self.process_table.setColumnWidth(packaging_start_col + 1, 140) # 称重 - - # 删除这个重复的方法,下面的是重复定义 - # 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("检验")) - # - # # 包装区域(2列) - # packaging_start_col = 2 + self.inspection_columns - # self.process_table.setSpan(0, packaging_start_col, 1, 2) - # 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)) \ No newline at end of file + self.process_table.setColumnWidth(packaging_start_col + 1, 140) # 称重 \ No newline at end of file diff --git a/widgets/main_window.py b/widgets/main_window.py index b314b7d..301573b 100644 --- a/widgets/main_window.py +++ b/widgets/main_window.py @@ -3,15 +3,18 @@ import sys import logging import json from datetime import datetime +from pathlib import Path # 导入PySide6 -from PySide6.QtWidgets import QWidget, QMessageBox, QTableWidgetItem, QStackedWidget, QLabel +from PySide6.QtWidgets import ( + QWidget, QMessageBox, QTableWidgetItem, QStackedWidget, QLabel, QMainWindow, + QTableWidget, QMenu +) from PySide6.QtCore import Qt, QTimer from PySide6.QtGui import QBrush, QColor # 导入UI from ui.main_window_ui import MainWindowUI - # 导入相机显示组件和设置组件 from widgets.camera_display_widget import CameraDisplayWidget from widgets.camera_settings_widget import CameraSettingsWidget @@ -83,6 +86,13 @@ class MainWindow(MainWindowUI): # 配置检验列 - 使用检验配置管理器获取启用的列数和标题 self.update_inspection_columns() + # 设置表格上下文菜单 + self.process_table.setContextMenuPolicy(Qt.CustomContextMenu) + self.process_table.customContextMenuRequested.connect(self.show_table_context_menu) + + # 加载未完成的检验数据 + self.load_unfinished_inspection_data() + logging.info(f"主窗口已创建,用户: {user_name}") def load_config(self): @@ -173,6 +183,9 @@ class MainWindow(MainWindowUI): # 更新检验列配置 self.update_inspection_columns() + # 加载未完成的检验数据 + self.load_unfinished_inspection_data() + # 只有在相机启用时处理相机显示 if self.camera_enabled and hasattr(self, 'camera_display'): # 如果相机已连接,直接开始显示相机画面 @@ -282,11 +295,462 @@ class MainWindow(MainWindowUI): if order_text: logging.info(f"输入的工程号: {order_text}") - QMessageBox.information(self, "工程号确认", f"您输入的工程号是: {order_text}") - # 这里可以添加其他工程号处理逻辑 + + # 在微丝产线表格中添加一条新记录 + self.add_new_inspection_row(order_text) + else: logging.warning("工程号为空") QMessageBox.warning(self, "输入提示", "请输入有效的工程号") # 处理完后可以清除焦点,让输入框失去焦点 - self.central_widget.setFocus() \ No newline at end of file + self.central_widget.setFocus() + + def add_new_inspection_row(self, order_id): + """在微丝产线表格中添加一条新记录 + + Args: + order_id: 工程号 + """ + try: + # 获取启用的检验配置 + enabled_configs = self.inspection_manager.get_enabled_configs() + + # 固定的数据起始行索引 + data_start_row = 2 # 数据从第3行开始 + + # 在指定行索引插入新行 + self.process_table.insertRow(data_start_row) + + # 更新序号 - 所有现有行序号+1 + for row in range(data_start_row + 1, self.process_table.rowCount()): + seq_item = self.process_table.item(row, 0) + if seq_item: + try: + current_seq = int(seq_item.text()) + seq_item.setText(str(current_seq + 1)) + except ValueError: + pass + + # 添加工程号到表格的第二列 + item = QTableWidgetItem(order_id) + item.setTextAlignment(Qt.AlignCenter) + self.process_table.setItem(data_start_row, 1, item) + + # 添加序号到表格的第一列 - 新行始终是第1条 + item = QTableWidgetItem("1") + item.setTextAlignment(Qt.AlignCenter) + self.process_table.setItem(data_start_row, 0, item) + + # 检验列设置为可编辑状态 + for i, config in enumerate(enabled_configs): + col_index = 2 + i # 检验列从第3列开始 + + # 创建空的可编辑单元格 + item = QTableWidgetItem("") + item.setTextAlignment(Qt.AlignCenter) + # 设置单元格属性以标识其关联的检验项 + item.setData(Qt.UserRole, config.get('id')) + self.process_table.setItem(data_start_row, col_index, item) + + # 包装列设置为可编辑状态 + packaging_start_col = 2 + len(enabled_configs) + for i in range(2): # 贴标和称重 + col_index = packaging_start_col + i + item = QTableWidgetItem("") + item.setTextAlignment(Qt.AlignCenter) + self.process_table.setItem(data_start_row, col_index, item) + + # 设置表格为可编辑状态 + self.process_table.setEditTriggers(QTableWidget.DoubleClicked | QTableWidget.EditKeyPressed) + + # 连接单元格内容变更信号 + # 断开之前的连接(如果有) + try: + self.process_table.cellChanged.disconnect(self.handle_inspection_cell_changed) + except: + pass # 如果没有连接过,会抛出异常,忽略即可 + + # 重新连接信号 + self.process_table.cellChanged.connect(self.handle_inspection_cell_changed) + + # 选中新添加的行 + self.process_table.selectRow(data_start_row) + + # 限制最大行数 + self.limit_table_rows(10) # 最多保留10行数据 + + logging.info(f"已添加工程号 {order_id} 的新记录,显示在第1条") + + except Exception as e: + logging.error(f"添加新记录失败: {str(e)}") + QMessageBox.warning(self, "添加失败", f"添加新记录失败: {str(e)}") + + def limit_table_rows(self, max_rows): + """限制表格最大行数 + + Args: + max_rows: 最大行数(不包括表头行) + """ + try: + # 计算数据总行数 + data_rows = self.process_table.rowCount() - 2 # 减去表头行 + + # 如果超过最大行数,删除多余的行 + if data_rows > max_rows: + # 要删除的行数 + rows_to_remove = data_rows - max_rows + + # 从最后一行开始删除 + for i in range(rows_to_remove): + self.process_table.removeRow(self.process_table.rowCount() - 1) + + logging.info(f"已限制表格最大行数为 {max_rows} 行数据,删除了 {rows_to_remove} 行") + + except Exception as e: + logging.error(f"限制表格行数失败: {str(e)}") + + def handle_inspection_cell_changed(self, row, column): + """处理检验单元格内容变更 + + Args: + row: 行索引 + column: 列索引 + """ + try: + # 只处理数据行的检验列变更 + if row < 2: # 忽略表头行 + return + + # 忽略首尾两列(序号和工程号) + if column < 2: + return + + # 获取工程号 + order_id_item = self.process_table.item(row, 1) + if not order_id_item: + return + + order_id = order_id_item.text().strip() + if not order_id: + return + + # 获取启用的检验配置 + enabled_configs = self.inspection_manager.get_enabled_configs() + + # 判断是否是检验列(非包装列) + packaging_start_col = 2 + len(enabled_configs) + if column >= 2 and column < packaging_start_col: + # 是检验列 + config_index = column - 2 + if config_index < len(enabled_configs): + config = enabled_configs[config_index] + + # 获取单元格内容 + cell_item = self.process_table.item(row, column) + if not cell_item: + return + + value = cell_item.text().strip() + + # 显示临时状态消息 + self.statusBar().showMessage(f"正在保存检验数据: {config['display_name']}={value}", 1000) + + # 验证数据有效性 + if self.validate_inspection_value(config, value): + # 设置单元格颜色为通过 + cell_item.setBackground(QBrush(QColor("#c8e6c9"))) # 浅绿色 + status = 'pass' + else: + # 设置单元格颜色为警告 + cell_item.setBackground(QBrush(QColor("#fff9c4"))) # 浅黄色 + status = 'warning' + + # 保存到数据库 + self.save_inspection_data(order_id, config['position'], config['id'], value, status) + + except Exception as e: + logging.error(f"处理检验单元格变更失败: {str(e)}") + self.statusBar().showMessage(f"处理检验数据失败: {str(e)[:50]}...", 3000) + + def validate_inspection_value(self, config, value): + """验证检验值是否有效 + + Args: + config: 检验配置 + value: 检验值 + + Returns: + bool: 是否有效 + """ + try: + # 检查值是否为空 + if not value and config.get('required', False): + return False + + # 根据数据类型验证 + data_type = config.get('data_type') + + if data_type == 'number': + # 数值类型验证 + try: + num_value = float(value) + min_value = config.get('min_value') + max_value = config.get('max_value') + + if min_value is not None and num_value < min_value: + return False + + if max_value is not None and num_value > max_value: + return False + + return True + except ValueError: + return False + + elif data_type == 'enum': + # 枚举类型验证 + enum_values = config.get('enum_values') + if enum_values and isinstance(enum_values, list): + return value in enum_values + return False + + # 文本类型不做特殊验证 + return True + + except Exception as e: + logging.error(f"验证检验值失败: {str(e)}") + return False + + def save_inspection_data(self, order_id, position, config_id, value, status): + """保存检验数据到数据库 + + Args: + order_id: 工程号 + position: 位置序号 + config_id: 配置ID + value: 检验值 + status: 状态 + """ + try: + from dao.inspection_dao import InspectionDAO + inspection_dao = InspectionDAO() + + # 记录保存前的详细日志 + logging.info(f"正在保存检验数据: 工程号={order_id}, 位置={position}, 配置ID={config_id}, 值={value}, 状态={status}") + + # 构建数据 + data = [{ + 'position': position, + 'config_id': config_id, + 'value': value, + 'status': status, + 'remark': '' + }] + + # 保存到数据库 + result = inspection_dao.save_inspection_data(order_id, data) + + if result: + logging.info(f"已成功保存工程号 {order_id} 的检验数据,位置: {position}, 值: {value}") + # 显示临时状态消息 + self.statusBar().showMessage(f"已保存检验数据:{value}", 3000) + else: + logging.warning(f"保存工程号 {order_id} 的检验数据失败") + # 显示错误消息 + self.statusBar().showMessage(f"保存检验数据失败", 3000) + + except Exception as e: + logging.error(f"保存检验数据失败: {str(e)}") + # 显示错误消息 + self.statusBar().showMessage(f"保存检验数据错误: {str(e)[:50]}...", 3000) + + def show_table_context_menu(self, pos): + """显示表格上下文菜单 + + Args: + pos: 鼠标位置 + """ + try: + # 获取当前单元格 + cell_index = self.process_table.indexAt(pos) + if not cell_index.isValid(): + return + + row = cell_index.row() + column = cell_index.column() + + # 只对数据行和检验列显示上下文菜单 + if row < 2: # 忽略表头行 + return + + # 获取工程号 + order_id_item = self.process_table.item(row, 1) + if not order_id_item: + return + + order_id = order_id_item.text().strip() + if not order_id: + return + + # 创建上下文菜单 + menu = QMenu(self) + + # 获取启用的检验配置 + enabled_configs = self.inspection_manager.get_enabled_configs() + + # 判断是否是检验列(非包装列) + packaging_start_col = 2 + len(enabled_configs) + if column >= 2 and column < packaging_start_col: + # 是检验列 + config_index = column - 2 + if config_index < len(enabled_configs): + config = enabled_configs[config_index] + position = config.get('position') + + # 添加查询数据库菜单项 + check_action = menu.addAction("检查数据库记录") + check_action.triggered.connect(lambda: self.check_database_record(order_id, position)) + + # 显示菜单 + menu.exec_(self.process_table.viewport().mapToGlobal(pos)) + + except Exception as e: + logging.error(f"显示表格上下文菜单失败: {str(e)}") + + def check_database_record(self, order_id, position): + """检查数据库记录 + + Args: + order_id: 工程号 + position: 位置序号 + """ + try: + from dao.inspection_dao import InspectionDAO + inspection_dao = InspectionDAO() + + # 获取检验数据 + inspection_data = inspection_dao.get_inspection_data_by_order(order_id) + + # 查找对应位置的数据 + matching_data = None + for data in inspection_data: + if data.get('position') == position: + matching_data = data + break + + # 显示结果 + if matching_data: + value = matching_data.get('value') + status = matching_data.get('status') + + message = f"数据库记录:\n\n" + message += f"工程号: {order_id}\n" + message += f"位置: {position}\n" + message += f"值: {value}\n" + message += f"状态: {status}\n" + + QMessageBox.information(self, "数据库记录", message) + else: + QMessageBox.warning(self, "数据库记录", f"未找到工程号 {order_id} 位置 {position} 的数据") + + except Exception as e: + logging.error(f"检查数据库记录失败: {str(e)}") + QMessageBox.warning(self, "查询失败", f"检查数据库记录失败: {str(e)}") + + def load_unfinished_inspection_data(self): + """加载未完成的检验数据并显示在表格中""" + try: + # 使用InspectionDAO获取未完成的检验数据 + from dao.inspection_dao import InspectionDAO + inspection_dao = InspectionDAO() + + # 使用get_inspection_data_unfinished获取未完成的数据 + unfinished_data = inspection_dao.get_inspection_data_unfinished() + + if not unfinished_data: + logging.info("没有未完成的检验数据") + return + + logging.info(f"已加载未完成的检验数据,共 {len(unfinished_data)} 条记录") + + # 获取启用的检验配置 + enabled_configs = self.inspection_manager.get_enabled_configs() + + # 按工程号分组 + orders_data = {} + for data in unfinished_data: + order_id = data['order_id'] + if order_id not in orders_data: + orders_data[order_id] = [] + orders_data[order_id].append(data) + + # 断开单元格变更信号,避免加载过程中触发保存 + try: + self.process_table.cellChanged.disconnect(self.handle_inspection_cell_changed) + except: + pass + + # 清空表格现有数据行 + while self.process_table.rowCount() > 2: + self.process_table.removeRow(2) + + # 添加数据到表格 + row_idx = 2 # 从第3行开始添加数据 + for order_id, items in orders_data.items(): + # 添加新行 + self.process_table.insertRow(row_idx) + + # 添加序号到第一列 + seq_item = QTableWidgetItem(str(row_idx - 1)) + seq_item.setTextAlignment(Qt.AlignCenter) + self.process_table.setItem(row_idx, 0, seq_item) + + # 添加工程号到第二列 + order_item = QTableWidgetItem(order_id) + order_item.setTextAlignment(Qt.AlignCenter) + self.process_table.setItem(row_idx, 1, order_item) + + # 添加检验数据 + for item in items: + position = item['position'] + value = item['value'] if item['value'] else "" + status = item['status'] + config_id = item['config_id'] + + # 找到对应的列索引 + col_index = None + for i, config in enumerate(enabled_configs): + if config.get('position') == position: + col_index = 2 + i # 检验列从第3列开始 + break + + if col_index is not None: + # 创建单元格并设置值 + cell_item = QTableWidgetItem(str(value)) + cell_item.setTextAlignment(Qt.AlignCenter) + # 存储配置ID,用于保存时确定是哪个检验项 + cell_item.setData(Qt.UserRole, config_id) + + # 根据状态设置单元格颜色 + if status == 'fail': + cell_item.setBackground(QBrush(QColor("#ffcdd2"))) # 浅红色 + elif status == 'warning': + cell_item.setBackground(QBrush(QColor("#fff9c4"))) # 浅黄色 + elif status == 'pass': + cell_item.setBackground(QBrush(QColor("#c8e6c9"))) # 浅绿色 + + # 设置单元格 + self.process_table.setItem(row_idx, col_index, cell_item) + + row_idx += 1 + + # 设置表格为可编辑状态 + self.process_table.setEditTriggers(QTableWidget.DoubleClicked | QTableWidget.EditKeyPressed) + + # 重新连接单元格变更信号 + self.process_table.cellChanged.connect(self.handle_inspection_cell_changed) + + except Exception as e: + logging.error(f"加载未完成的检验数据失败: {str(e)}") + QMessageBox.warning(self, "加载失败", f"加载未完成的检验数据失败: {str(e)}") \ No newline at end of file