feat: 在加载和卸载对话框中添加焦点跟踪器功能,并在主窗口中实现焦点变化记录

This commit is contained in:
zhu-mengmeng 2025-07-17 13:15:47 +08:00
parent a8c4a929ff
commit dce6f4a14a
4 changed files with 175 additions and 16 deletions

111
utils/focus_tracker.py Normal file
View File

@ -0,0 +1,111 @@
from PySide6.QtWidgets import QApplication, QLineEdit, QComboBox
from PySide6.QtCore import QObject, Signal
import logging
class FocusTracker(QObject):
"""焦点跟踪器,用于跟踪当前焦点所在的输入框"""
# 定义单例
_instance = None
# 信号:当焦点变化时触发
focus_changed = Signal(object)
@classmethod
def get_instance(cls):
"""获取单例实例"""
if cls._instance is None:
cls._instance = FocusTracker()
return cls._instance
def __init__(self):
"""初始化焦点跟踪器"""
if FocusTracker._instance is not None:
raise Exception("FocusTracker是单例类请使用get_instance()方法获取实例")
super().__init__()
self._current_focus = None
self._initialized = False
def initialize(self):
"""初始化焦点跟踪"""
if self._initialized:
return
# 连接应用程序的焦点变化信号
app = QApplication.instance()
if app:
app.focusChanged.connect(self._on_focus_changed)
self._initialized = True
logging.info("焦点跟踪器已初始化")
else:
logging.error("无法获取QApplication实例焦点跟踪器初始化失败")
def _on_focus_changed(self, old, now):
"""焦点变化处理"""
# 关注QLineEdit和QComboBox控件
if isinstance(now, (QLineEdit, QComboBox)):
self._current_focus = now
self.focus_changed.emit(now)
widget_type = "输入框" if isinstance(now, QLineEdit) else "下拉框"
logging.debug(f"焦点变化到{widget_type}: {now.objectName()}")
def get_current_focus(self):
"""获取当前焦点所在的控件"""
return self._current_focus
def set_text_and_trigger_enter(self, text):
"""设置当前焦点控件的文本并触发回车事件"""
if not self._current_focus:
logging.warning("当前没有焦点控件,无法设置文本和触发回车事件")
return False
# 创建回车键事件
from PySide6.QtGui import QKeyEvent
from PySide6.QtCore import Qt, QEvent
key_event = QKeyEvent(QEvent.KeyPress, Qt.Key_Return, Qt.NoModifier)
# 根据控件类型处理
if isinstance(self._current_focus, QLineEdit):
# 设置文本
self._current_focus.setText(text)
# 发送事件到当前焦点控件
QApplication.sendEvent(self._current_focus, key_event)
logging.info(f"已将文本 '{text}' 设置到输入框并触发回车事件")
return True
elif isinstance(self._current_focus, QComboBox):
# 对于ComboBox先查找匹配的项
combo_box = self._current_focus
# 查找完全匹配的项
index = combo_box.findText(text)
if index >= 0:
combo_box.setCurrentIndex(index)
logging.info(f"已在下拉框中选择匹配项: '{text}'")
else:
# 如果没有完全匹配的项设置为编辑文本如果ComboBox是可编辑的
if combo_box.isEditable():
combo_box.setEditText(text)
logging.info(f"已将文本 '{text}' 设置到可编辑下拉框")
else:
logging.warning(f"下拉框中没有匹配项 '{text}',且下拉框不可编辑")
return False
# 发送事件到当前焦点控件
QApplication.sendEvent(combo_box, key_event)
# 如果ComboBox有activated信号手动触发
try:
if hasattr(combo_box, 'activated'):
combo_box.activated.emit(combo_box.currentIndex())
logging.debug("已触发下拉框的activated信号")
except Exception as e:
logging.error(f"触发下拉框activated信号失败: {e}")
return True
else:
logging.warning(f"不支持的控件类型: {type(self._current_focus)}")
return False

View File

@ -31,6 +31,10 @@ class LoadingDialog(LoadingDialogUI):
# 设置对话框特性按下Escape键才能关闭
self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
# 确保焦点跟踪器能够跟踪此对话框中的输入框
from utils.focus_tracker import FocusTracker
self.focus_tracker = FocusTracker.get_instance()
# 绑定事件
self.setup_connections()

View File

@ -67,6 +67,14 @@ class MainWindow(MainWindowUI):
self.corp_name = corp_name
self.corp_id = corp_id
# 初始化焦点跟踪器
from utils.focus_tracker import FocusTracker
self.focus_tracker = FocusTracker.get_instance()
self.focus_tracker.initialize()
# 连接焦点变化信号
self.focus_tracker.focus_changed.connect(self._log_focus_widget_info)
# 初始化系统变量
self._current_weight = 0.0 # 当前重量
self._last_weight_time = 0 # 上次称重时间
@ -2895,23 +2903,33 @@ class MainWindow(MainWindowUI):
# 提取扫码数据,格式为"扫码数据: xxx"
if "扫码数据:" in data_str:
gc_note = data_str.split("扫码数据:")[1].strip()
logging.info(f"提取到工程号: {gc_note}")
scan_data = data_str.split("扫码数据:")[1].strip()
logging.info(f"提取到扫码数据: {scan_data}")
# 临时断开returnPressed信号连接避免setText触发信号
try:
self.order_edit.returnPressed.disconnect(self.handle_order_enter)
except Exception:
logging.debug("returnPressed信号未连接或断开失败")
# 使用焦点跟踪器设置文本并触发回车事件
from utils.focus_tracker import FocusTracker
focus_tracker = FocusTracker.get_instance()
# 设置工程号到输入框
self.order_edit.setText(gc_note)
# 重新连接returnPressed信号
self.order_edit.returnPressed.connect(self.handle_order_enter)
# 调用一次handle_order_enter方法
self.handle_order_enter()
if focus_tracker.set_text_and_trigger_enter(scan_data):
logging.info(f"已将扫码数据 '{scan_data}' 设置到当前焦点输入框并触发回车事件")
else:
# 如果没有焦点输入框,则默认设置到工程号输入框
logging.info(f"没有焦点输入框,默认将扫码数据设置到工程号输入框")
# 临时断开returnPressed信号连接避免setText触发信号
try:
self.order_edit.returnPressed.disconnect(self.handle_order_enter)
except Exception:
logging.debug("returnPressed信号未连接或断开失败")
# 设置工程号到输入框
self.order_edit.setText(scan_data)
# 重新连接returnPressed信号
self.order_edit.returnPressed.connect(self.handle_order_enter)
# 调用一次handle_order_enter方法
self.handle_order_enter()
else:
logging.warning(f"收到的数据不包含扫码数据标记: {data_str}")
except Exception as e:
@ -3585,4 +3603,26 @@ class MainWindow(MainWindowUI):
except Exception as e:
logging.error(f"更新订单数量和产量统计数据失败: {str(e)}")
import traceback
logging.error(traceback.format_exc())
logging.error(traceback.format_exc())
def _log_focus_widget_info(self, widget):
"""记录当前焦点控件的信息,用于调试"""
try:
from PySide6.QtWidgets import QLineEdit, QComboBox
widget_type = "未知"
if isinstance(widget, QLineEdit):
widget_type = "输入框"
elif isinstance(widget, QComboBox):
widget_type = "下拉框"
widget_name = widget.objectName() if widget else ""
widget_text = ""
if isinstance(widget, QLineEdit):
widget_text = widget.text()
elif isinstance(widget, QComboBox):
widget_text = widget.currentText()
logging.info(f"当前焦点控件: 类型={widget_type}, 名称={widget_name}, 文本={widget_text}")
except Exception as e:
logging.error(f"记录焦点控件信息失败: {e}")

View File

@ -31,6 +31,10 @@ class UnloadingDialog(UnloadingDialogUI):
# 设置对话框特性按下Escape键才能关闭
self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
# 确保焦点跟踪器能够跟踪此对话框中的输入框
from utils.focus_tracker import FocusTracker
self.focus_tracker = FocusTracker.get_instance()
# 初始化托盘类型下拉列表
self.init_pallet_types()