diff --git a/config/app_config.json b/config/app_config.json index d527db1..66d41c5 100644 --- a/config/app_config.json +++ b/config/app_config.json @@ -120,7 +120,7 @@ } }, "electricity": { - "auto_start": false, + "auto_start": true, "interval_minutes": 30 } } \ No newline at end of file diff --git a/widgets/main_window.py b/widgets/main_window.py index 75d4eaf..e6abcda 100644 --- a/widgets/main_window.py +++ b/widgets/main_window.py @@ -13,7 +13,7 @@ from utils.register_handlers import ( WeightDataHandler, LabelSignalHandler, MachineStatusHandlers, - LoadingFeedbackHandler, + LoadingFeedbackHandler, UnloadingFeedbackHandler, Error1Handler, Error2Handler, @@ -1236,6 +1236,20 @@ class MainWindow(MainWindowUI): row: 行索引 column: 列索引 """ + # 防抖机制:记录上次处理的单元格位置和时间 + current_time = time.time() + last_cell_key = f"{row}_{column}" + last_process_time = getattr(self, '_last_cell_change_time', 0) + last_cell = getattr(self, '_last_cell_changed', '') + + # 如果是同一单元格且间隔小于0.5秒,则忽略此次调用 + if last_cell == last_cell_key and current_time - last_process_time < 0.5: + return + + # 更新最后处理的单元格和时间 + self._last_cell_changed = last_cell_key + self._last_cell_change_time = current_time + try: # 只处理数据行的检验列变更 if row < 2: # 忽略表头行 @@ -1352,6 +1366,20 @@ class MainWindow(MainWindowUI): value: 检验值 status: 状态 """ + # 防抖机制:记录上次保存的数据和时间 + current_time = time.time() + save_key = f"{gc_note}_{position}_{config_id}_{value}" + last_save_time = getattr(self, '_last_save_time', 0) + last_save_key = getattr(self, '_last_save_key', '') + + # 如果是相同的数据且间隔小于0.5秒,则忽略此次保存 + if last_save_key == save_key and current_time - last_save_time < 0.5: + return + + # 更新最后保存的数据和时间 + self._last_save_key = save_key + self._last_save_time = current_time + try: from dao.inspection_dao import InspectionDAO inspection_dao = InspectionDAO() @@ -1392,6 +1420,18 @@ class MainWindow(MainWindowUI): # 获取当前托盘号,用于日志记录 tray_id = self.tray_edit.currentText() + # 防抖机制:记录上次加载的时间 + current_time = time.time() + last_safe_load_time = getattr(self, '_last_safe_load_time', 0) + + # 如果间隔小于0.5秒,则忽略此次加载 + if current_time - last_safe_load_time < 0.5: + logging.debug(f"_safe_load_data 被频繁调用,忽略此次请求 (托盘号: {tray_id})") + return + + # 更新最后加载的时间 + self._last_safe_load_time = current_time + if self._loading_data_in_progress: # 如果已经在加载数据,不要再次触发 logging.debug(f"已有数据加载正在进行,忽略此次请求 (托盘号: {tray_id})") @@ -1416,12 +1456,26 @@ class MainWindow(MainWindowUI): """加载未完成的检验数据并显示在表格中""" # 注意:此方法通常应通过_safe_load_data调用,以防止循环 try: + # 获取托盘号 + tray_id = self.tray_edit.currentText() + + # 防止短时间内重复加载相同数据 + current_time = time.time() + last_load_time = getattr(self, '_last_load_time', 0) + last_load_tray = getattr(self, '_last_load_tray', '') + + # 如果是同一托盘且间隔小于1秒,则忽略此次加载 + if last_load_tray == tray_id and current_time - last_load_time < 1.0: + logging.debug(f"忽略重复加载托盘 {tray_id} 的数据,间隔太短") + return + + # 更新最后加载的托盘和时间 + self._last_load_tray = tray_id + self._last_load_time = current_time + # 使用InspectionDAO获取未完成的检验数据 from dao.inspection_dao import InspectionDAO inspection_dao = InspectionDAO() - - # 获取托盘号 - tray_id = self.tray_edit.currentText() # 使用get_inspection_data_unfinished获取未完成的数据 unfinished_data = inspection_dao.get_inspection_data_unfinished(tray_id) @@ -1641,6 +1695,7 @@ class MainWindow(MainWindowUI): except Exception as e: logging.error(f"加载已完成检验数据到包装记录失败: {str(e)}") QMessageBox.warning(self, "加载失败", f"加载已完成检验数据到包装记录失败: {str(e)}") + def show_pack_item(self): """显示包装记录""" try: @@ -1725,6 +1780,7 @@ class MainWindow(MainWindowUI): logging.error(f"显示包装记录失败: {str(e)}") self.record_table.blockSignals(False) # 确保信号被恢复 QMessageBox.warning(self, "显示失败", f"显示包装记录失败: {str(e)}") + def update_package_statistics(self): """更新包装记录统计数据""" try: @@ -1755,7 +1811,7 @@ class MainWindow(MainWindowUI): except Exception as e: logging.error(f"更新包装记录统计数据失败: {str(e)}") - + def show_table_context_menu(self, pos): """显示表格上下文菜单 @@ -2518,6 +2574,7 @@ class MainWindow(MainWindowUI): try: # 获取Modbus客户端(现在使用连接池,不会每次都创建新连接) client = modbus.get_client() + time.sleep(0.5) if not client: logging.error("无法获取Modbus客户端连接") return @@ -2742,25 +2799,6 @@ class MainWindow(MainWindowUI): """处理寄存器变化""" logging.info(f"[处理] 寄存器D{address}变化: {value}") - # # 当D0寄存器有值时,填充上料按钮样式 - # if address == 0 and value > 0: - # self.fill_input_button_style() - # logging.info(f"D0寄存器有值({value}),填充上料按钮样式") - - # # 当D4寄存器有值时,填充下料按钮样式 - # elif address == 4 and value > 0: - # self.fill_output_button_style() - # logging.info(f"D4寄存器有值({value}),填充下料按钮样式") - - # # 当D0寄存器为 0 时,恢复上料按钮样式 - # if address == 0 and value == 0: - # self.restore_input_button_style() - # logging.info(f"D0寄存器为 0 ,恢复上料按钮样式") - - # # 当D4寄存器为 0 时,恢复下料按钮样式 - # elif address == 4 and value == 0: - # self.restore_output_button_style() - # logging.info(f"D4寄存器为 0 ,恢复下料按钮样式") # D2寄存器控制上料按钮样式 if address == 2 and value == 0: self.restore_input_button_style() @@ -4581,7 +4619,7 @@ class MainWindow(MainWindowUI): status = inspection_dao.get_product_status(self._current_order_code, row_gc_note, tray_id) if status == target_status: logging.info(f"找到状态为{target_status}的行: {row}, 工程号: {row_gc_note}") - return row + return row # 找到第一个匹配的行就立即返回 # 如果从当前处理行开始没找到,从头开始搜索 if self._current_processing_row is not None and self._current_processing_row > 2: @@ -4594,7 +4632,7 @@ class MainWindow(MainWindowUI): status = inspection_dao.get_product_status(self._current_order_code, row_gc_note, tray_id) if status == target_status: logging.info(f"从头开始找到状态为{target_status}的行: {row}, 工程号: {row_gc_note}") - return row + return row # 找到第一个匹配的行就立即返回 logging.warning(f"未找到状态为{target_status}的行") return None