111 lines
4.3 KiB
Python
111 lines
4.3 KiB
Python
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 |