jiateng_ws/utils/focus_tracker.py

111 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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