PyQt5中Tamil99键盘布局下QLineEdit实时输入异常解决问询
解决PyQt5中Tamil99键盘布局下QLineEdit实时过滤失效问题
问题背景
在Windows 10上开发PyQt5应用,包含3个QLineEdit和1个QListWidget:
- 第一个QLineEdit:英语(美国)输入
- 第二个QLineEdit:泰米尔语拼音输入法
- 第三个QLineEdit:Tamil99键盘布局
当使用Tamil99键盘布局输入时(比如同时按j+Q输入“பா”,n+q输入“லா”),QLineEdit的textChanged信号无法在每次按键时触发,导致QListWidget的过滤列表不能实时更新。
解决方案
Tamil99这类依赖组合键输入的键盘布局会延迟发送textChanged信号,直到完整的字符输入序列完成。我们需要通过事件过滤器捕获所有按键事件,并主动触发过滤逻辑,确保列表实时更新。
关键修改点
- 扩展事件过滤器,添加对
KeyPress事件的处理,针对Tamil99输入框强制触发过滤 - 新增
filter_list_for_textbox方法,专门处理指定输入框的文本过滤 - 优化过滤逻辑,区分英语和泰米尔语的文本匹配规则(泰米尔语无需转小写)
- 用
QTimer.singleShot延迟获取文本,确保输入法完成组合键的字符转换
修改后的完整代码
import sys from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * import win32api import py_win_keyboard_layout class Diff_Language(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Input Different Languages in Different Textboxes") self.lbl1 = QLabel("Input Language - English (US)") self.tbox1 = QLineEdit() self.tbox1.setFont(QFont('Arial Unicode MS', 10, QFont.Bold)) self.tbox1.installEventFilter(self) self.tbox1.setMaxLength(25) self.tbox1.textChanged.connect(self.filter_list) self.lbl2 = QLabel("Input Language - Tamil Phonetic") self.tbox2 = QLineEdit() self.tbox2.setFont(QFont('Arial Unicode MS', 30, QFont.Bold)) self.tbox2.installEventFilter(self) self.tbox2.setMaxLength(25) self.tbox2.textChanged.connect(self.filter_list) self.lbl3 = QLabel("Input Language - Tamil99 Keyboard") self.tbox3 = QLineEdit() self.tbox3.setFont(QFont('Arial Unicode MS', 12, QFont.Bold)) self.tbox3.installEventFilter(self) self.tbox3.setMaxLength(25) self.tbox3.textChanged.connect(self.filter_list) self.listbox = QListWidget() add_items = ["பாலாஜி","பாலா","பால்","Red", "Dark red", "Light Red", "Redish Blue", "Redish Green", "Green","Blue","Dark Blue", "Dark Green"] self.original_items = add_items.copy() self.listbox.addItems(add_items) self.vbox = QVBoxLayout() self.vbox.addWidget(self.lbl1) self.vbox.addWidget(self.tbox1) self.vbox.addWidget(self.lbl2) self.vbox.addWidget(self.tbox2) self.vbox.addWidget(self.lbl3) self.vbox.addWidget(self.tbox3) self.vbox.addWidget(self.listbox) self.setLayout(self.vbox) self.current_layout = 0x409 def eventFilter(self, obj, event): if event.type() == QEvent.FocusIn: self.handle_focus_in(obj) elif event.type() == QEvent.KeyPress: QTimer.singleShot(10, lambda: self.filter_list_for_textbox(obj)) return super().eventFilter(obj, event) def filter_list_for_textbox(self, textbox): if textbox in [self.tbox1, self.tbox2, self.tbox3]: text = textbox.text() filtered_items = [] for item in self.original_items: if text.lower() in item.lower() if item.isascii() else text in item: filtered_items.append(item) self.listbox.clear() self.listbox.addItems(filtered_items) def handle_focus_in(self, textbox): if textbox == self.tbox1: self.current_layout = win32api.LoadKeyboardLayout("00020409") elif textbox == self.tbox2: self.current_layout = 0x449 elif textbox == self.tbox3: self.current_layout = win32api.LoadKeyboardLayout("00020449") py_win_keyboard_layout.change_foreground_window_keyboard_layout(self.current_layout) self.listbox.clear() self.listbox.addItems(self.original_items) def filter_list(self): text = self.sender().text() filtered_items = [] for item in self.original_items: if text.lower() in item.lower() if item.isascii() else text in item: filtered_items.append(item) self.listbox.clear() self.listbox.addItems(filtered_items) def handle_focus_out(self, textbox): self.current_layout = win32api.LoadKeyboardLayout("00020409") py_win_keyboard_layout.change_foreground_window_keyboard_layout(self.current_layout) def closeEvent(self, event): self.current_layout = win32api.LoadKeyboardLayout("00020409") py_win_keyboard_layout.change_foreground_window_keyboard_layout(self.current_layout) event.accept() def main(): app = QApplication(sys.argv) mainscreen = Diff_Language() app.setStyle("Fusion") mainscreen.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
内容的提问来源于stack exchange,提问作者Bala
相关产品推荐
相关产品推荐

