From ffe4be311ac2a0db7185cfcf09d5e3df74d7a575 Mon Sep 17 00:00:00 2001 From: Horse861 <929110464@qq.com> Date: Mon, 27 Oct 2025 10:30:57 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat(=E8=BE=93=E5=85=A5=E5=A4=84=E7=90=86):?= =?UTF-8?q?=20=E5=AE=9E=E7=8E=B0=E9=80=80=E6=A0=BC=E9=94=AE=E5=92=8C?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=94=AE=E7=9A=84=E5=AE=8C=E6=95=B4=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加输入处理器对退格键和删除键的处理,包括缓冲区更新和信号发射 在文本编辑器中集成输入处理器,处理按键事件并保持原有编辑行为 更新学习模式下的文本显示逻辑,基于输入处理器状态同步内容 --- src/input_handler/input_processor.py | 20 +++++++++++++- src/ui/word_style_ui.py | 36 ++++++++++++++++++++++++ src/word_main_window.py | 41 ++++++++++++++++++++++++++-- 3 files changed, 93 insertions(+), 4 deletions(-) diff --git a/src/input_handler/input_processor.py b/src/input_handler/input_processor.py index 542bc0d..673a5fb 100644 --- a/src/input_handler/input_processor.py +++ b/src/input_handler/input_processor.py @@ -28,7 +28,25 @@ class InputProcessor(QObject): return False # 2. 根据按键类型处理(字符、功能键等) - # 3. 更新输入缓冲区 + # 处理退格键 + if key == '\b' or key == '\x7f': # 退格键 (\b) 或删除键 (\x7f) + if self.input_buffer: # 只有当输入缓冲区有内容时才处理 + # 删除最后一个字符 + deleted_char = self.input_buffer[-1] + self.input_buffer = self.input_buffer[:-1] + self.current_position = max(0, self.current_position - 1) + + # 发送退格信号,包含被删除的字符 + self.text_changed.emit('\b') + + # 发送按键信号用于记录 + self.key_pressed.emit(f"backspace_deleted:{deleted_char}") + + return True + else: + return False # 缓冲区为空,不处理退格 + + # 3. 更新输入缓冲区(普通字符) self.input_buffer += key self.current_position += 1 diff --git a/src/ui/word_style_ui.py b/src/ui/word_style_ui.py index 98c29f3..0716239 100644 --- a/src/ui/word_style_ui.py +++ b/src/ui/word_style_ui.py @@ -465,6 +465,42 @@ class WordTextEdit(QTextEdit): def __init__(self, parent=None): super().__init__(parent) self.setup_ui() + self.input_processor = None # 输入处理器引用 + + def set_input_processor(self, processor): + """设置输入处理器""" + self.input_processor = processor + + def keyPressEvent(self, event): + """重写按键事件处理""" + # 处理退格键 + if event.key() == Qt.Key_Backspace: + if self.input_processor: + # 使用输入处理器处理退格键 + self.input_processor.process_key_event('\b') + # 让父类处理实际的文本编辑逻辑 + super().keyPressEvent(event) + else: + # 如果没有输入处理器,使用默认行为 + super().keyPressEvent(event) + # 处理删除键 + elif event.key() == Qt.Key_Delete: + if self.input_processor: + # 使用输入处理器处理删除键 + self.input_processor.process_key_event('\x7f') + # 让父类处理实际的文本编辑逻辑 + super().keyPressEvent(event) + else: + # 如果没有输入处理器,使用默认行为 + super().keyPressEvent(event) + else: + # 处理其他按键 + if self.input_processor and len(event.text()) > 0: + # 处理普通字符输入 + self.input_processor.process_key_event(event.text()) + + # 让父类处理实际的文本编辑逻辑 + super().keyPressEvent(event) def setup_ui(self): """设置文本编辑区域样式""" diff --git a/src/word_main_window.py b/src/word_main_window.py index aa4e950..dbf3ffc 100644 --- a/src/word_main_window.py +++ b/src/word_main_window.py @@ -15,6 +15,7 @@ from services.network_service import NetworkService from typing_logic import TypingLogic from ui.word_style_ui import WeatherAPI from file_parser import FileParser +from input_handler.input_processor import InputProcessor class WeatherFetchThread(QThread): weather_fetched = pyqtSignal(dict) @@ -86,6 +87,9 @@ class WordStyleMainWindow(QMainWindow): # 临时文件管理 self.temp_files = [] # 跟踪创建的临时文件 + # 初始化输入处理器 + self.input_processor = InputProcessor() + # 初始化网络服务和WeatherAPI self.network_service = NetworkService() self.weather_api = WeatherAPI() @@ -455,6 +459,13 @@ class WordStyleMainWindow(QMainWindow): # 设置默认文档内容 self.text_edit.setPlainText("在此输入您的内容...") + # 连接输入处理器到文本编辑器 + self.text_edit.set_input_processor(self.input_processor) + + # 连接输入处理器的信号 + self.input_processor.text_changed.connect(self.on_input_text_changed) + self.input_processor.key_pressed.connect(self.on_key_pressed) + document_layout.addWidget(self.text_edit) # 创建图片显示区域 @@ -563,6 +574,29 @@ class WordStyleMainWindow(QMainWindow): self.is_modified = True self.update_window_title() + def on_input_text_changed(self, text): + """输入处理器文本变化处理""" + if self.view_mode == "learning" and self.imported_content: + # 在学习模式下,根据输入处理器的状态更新显示 + current_text = self.text_edit.toPlainText() + expected_text = self.imported_content[:len(text)] + + # 如果文本不匹配,更新显示 + if current_text != expected_text: + cursor = self.text_edit.textCursor() + self.text_edit.setPlainText(expected_text) + # 保持光标在末尾 + cursor.movePosition(QTextCursor.End) + self.text_edit.setTextCursor(cursor) + + def on_key_pressed(self, key): + """按键按下处理""" + # 更新状态栏显示当前按键 + if key in ['\b', '\x7f']: + self.status_bar.showMessage("退格键已处理", 1000) + else: + self.status_bar.showMessage(f"按键: {key}", 1000) + def handle_learning_mode_typing(self): """学习模式下的打字处理 - 从上次中断处继续显示学习文档C内容到文档A""" if self.imported_content and self.typing_logic: @@ -574,8 +608,9 @@ class WordStyleMainWindow(QMainWindow): # 只有在光标位于文本末尾时才显示新内容 if cursor_position == len(current_text): - # 计算应该显示的字符数(基于当前已显示的字符数) - chars_to_show = min(self.displayed_chars + 1, len(self.imported_content)) + # 使用输入处理器的状态来显示文本 + input_text = self.input_processor.input_buffer + chars_to_show = len(input_text) # 更新已显示字符数 self.displayed_chars = chars_to_show @@ -588,7 +623,7 @@ class WordStyleMainWindow(QMainWindow): self.typing_logic.typed_chars = self.displayed_chars self.typing_logic.current_index = self.displayed_chars - # 获取应该显示的文本部分(从上次中断处继续) + # 获取应该显示的文本部分(基于输入处理器的状态) display_text = self.imported_content[:self.displayed_chars] # 临时禁用文本变化信号,避免递归 From a562804a68ad16055a2fbc3cdab6cb787a186f0a Mon Sep 17 00:00:00 2001 From: Lesacm <1500309685@qq.com> Date: Mon, 27 Oct 2025 10:41:21 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8UI?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ui/word_style_ui.py | 59 ----------------------------------------- src/word_main_window.py | 6 +---- 2 files changed, 1 insertion(+), 64 deletions(-) diff --git a/src/ui/word_style_ui.py b/src/ui/word_style_ui.py index 0716239..e694b2c 100644 --- a/src/ui/word_style_ui.py +++ b/src/ui/word_style_ui.py @@ -530,65 +530,6 @@ class WordTextEdit(QTextEdit): # 设置光标宽度 self.setCursorWidth(2) -class WordStyleToolBar(QToolBar): - def __init__(self, parent=None): - super().__init__(parent) - self.setup_ui() - - def setup_ui(self): - """设置快速访问工具栏""" - self.setFixedHeight(30) - self.setStyleSheet(""" - QToolBar { - background-color: #f3f2f1; - border-bottom: 1px solid #d0d0d0; - spacing: 5px; - } - """) - - # 快速访问按钮 - save_btn = self.create_quick_button("保存", "Ctrl+S") - undo_btn = self.create_quick_button("撤销", "Ctrl+Z") - redo_btn = self.create_quick_button("重做", "Ctrl+Y") - - self.addWidget(save_btn) - self.addWidget(undo_btn) - self.addWidget(redo_btn) - self.addSeparator() - - # 添加弹性空间,将后面的按钮推到最右侧 - # 创建一个具有扩展策略的QWidget来实现spacer效果 - spacer = QWidget() - spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) - self.addWidget(spacer) - - # 添加批注、编辑、共享按钮到最右侧 - comment_btn = self.create_quick_button("批注", "") - edit_btn = self.create_quick_button("编辑", "") - share_btn = self.create_quick_button("共享", "") - - self.addWidget(comment_btn) - self.addWidget(edit_btn) - self.addWidget(share_btn) - - def create_quick_button(self, text, shortcut): - """创建快速访问按钮""" - btn = QToolButton() - btn.setText(text) - btn.setToolButtonStyle(Qt.ToolButtonTextOnly) - btn.setFixedSize(40, 25) - btn.setStyleSheet(""" - QToolButton { - border: none; - background-color: transparent; - font-size: 11px; - color: #333333; - } - QToolButton:hover { - background-color: #e1e1e1; - } - """) - return btn class WeatherAPI: def __init__(self): self.api_key = "f3d9201bf5974ed39caf0d6fe9567322" diff --git a/src/word_main_window.py b/src/word_main_window.py index dbf3ffc..41b49b8 100644 --- a/src/word_main_window.py +++ b/src/word_main_window.py @@ -10,7 +10,7 @@ from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer, QRect, QByteArray, QBu from PyQt5.QtGui import QFont, QPalette, QColor, QIcon, QPixmap, QTextCharFormat, QTextCursor, QTextDocument, QImage, QTextImageFormat, QTextFormat from ui.word_style_ui import (WordRibbon, WordStatusBar, WordTextEdit, - WordStyleToolBar) + ) from services.network_service import NetworkService from typing_logic import TypingLogic from ui.word_style_ui import WeatherAPI @@ -213,10 +213,6 @@ class WordStyleMainWindow(QMainWindow): # 创建菜单栏 self.create_menu_bar() - # 创建快速访问工具栏 - self.quick_toolbar = WordStyleToolBar() - self.addToolBar(Qt.TopToolBarArea, self.quick_toolbar) - # 创建Ribbon功能区 self.ribbon = WordRibbon() From 145316ec3d09e0ba7f11eeba1b31e33212c59964 Mon Sep 17 00:00:00 2001 From: Horse861 <929110464@qq.com> Date: Mon, 27 Oct 2025 10:46:05 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat(=E8=BE=93=E5=85=A5=E6=B3=95):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=AD=E6=96=87=E8=BE=93=E5=85=A5=E6=B3=95?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=8F=8A=E6=95=B4=E8=AF=8D=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现中文输入法的完整支持,包括: 1. 新增process_text_commit方法处理中文整词提交 2. 重写inputMethodEvent支持中文输入法事件处理 3. 优化typing_logic支持中文整词匹配和错误提示 4. 改进错误提示显示中文词组而非单个字符 --- src/input_handler/input_processor.py | 21 ++++ src/typing_logic.py | 144 ++++++++++++++++++++++++--- src/ui/word_style_ui.py | 44 +++++++- src/word_main_window.py | 42 ++++++-- 4 files changed, 226 insertions(+), 25 deletions(-) diff --git a/src/input_handler/input_processor.py b/src/input_handler/input_processor.py index 673a5fb..545b5ca 100644 --- a/src/input_handler/input_processor.py +++ b/src/input_handler/input_processor.py @@ -60,6 +60,27 @@ class InputProcessor(QObject): # 6. 返回处理结果 return True + def process_text_commit(self, text: str) -> bool: + """处理输入法提交的完整文本(支持中文输入)""" + if not text: + return False + + # 逐个处理提交的字符 + for char in text: + self.input_buffer += char + self.current_position += 1 + # 发送每个字符的text_changed信号 + self.text_changed.emit(char) + + # 发送完整的文本提交信号 + self.key_pressed.emit(f"text_commit:{text}") + + # 检查是否完成输入 + if self.expected_text and self.input_buffer == self.expected_text: + self.input_completed.emit() + + return True + def get_current_input(self) -> str: # 实现获取当前输入逻辑 diff --git a/src/typing_logic.py b/src/typing_logic.py index 6d020fb..df2ca00 100644 --- a/src/typing_logic.py +++ b/src/typing_logic.py @@ -19,6 +19,7 @@ class TypingLogic: """ 检查用户输入与学习材料的匹配情况 - 逐字符比较逻辑 + - 支持中文整词匹配 - 进度跟踪 - 准确率计算 - 返回字典包含: @@ -42,13 +43,31 @@ class TypingLogic: user_text = user_text[:self.total_chars] current_position = len(user_text) - # 检查当前输入是否正确 + # 检查当前输入是否正确(支持中文整词匹配) correct = True expected_char = '' if self.current_index < self.total_chars: expected_char = self.learning_content[self.current_index] - if len(user_text) > self.current_index and user_text[self.current_index] != expected_char: - correct = False + + # 中文整词匹配优化 + # 如果当前位置是中文文本的开始,尝试进行整词匹配 + if self._is_chinese_text_start(self.current_index): + # 获取期望的中文词组 + expected_word = self._get_chinese_word_at(self.current_index) + # 获取用户输入的对应部分 + user_word = user_text[self.current_index:min(self.current_index + len(expected_word), len(user_text))] + + # 如果用户输入的词组与期望词组匹配,则认为是正确的 + if user_word == expected_word: + correct = True + else: + # 如果整词不匹配,回退到逐字符匹配 + if len(user_text) > self.current_index and user_text[self.current_index] != expected_char: + correct = False + else: + # 非中文词组开始位置,使用逐字符匹配 + if len(user_text) > self.current_index and user_text[self.current_index] != expected_char: + correct = False else: # 已经完成所有输入 # 恢复原始的typed_chars值用于准确率计算 @@ -78,21 +97,35 @@ class TypingLogic: "accuracy": accuracy } - def update_position(self, user_text: str): + def update_position(self, user_text: str) -> dict: """ - 更新当前索引和错误计数 - - 根据用户输入更新当前位置 - - 计算并更新错误计数 + 更新当前位置并计算错误数 + - 支持中文整词匹配 + - 逐字符比较逻辑(回退机制) + - 错误计数 + - 位置更新 + - 返回字典包含: + * new_position: 整数,新的位置 + * error_count: 整数,错误数 + * completed: 布尔值,是否完成 """ - new_position = len(user_text) + # 更新当前索引位置 + self.current_index = len(user_text) + + # 重置错误计数 + self.error_count = 0 + + # 使用中文整词匹配优化错误计算 + self._calculate_errors_with_chinese_support(user_text) - # 计算新增的错误数 - for i in range(self.current_index, min(new_position, self.total_chars)): - if user_text[i] != self.learning_content[i]: - self.error_count += 1 + # 检查是否完成 + completed = self.current_index >= self.total_chars - # 更新当前索引 - self.current_index = new_position + return { + "new_position": self.current_index, + "error_count": self.error_count, + "completed": completed + } def get_expected_text(self, length: int = 10) -> str: """ @@ -236,4 +269,85 @@ class TypingLogic: return 0.0 finally: # 清除递归保护标志 - self._calculating_accuracy = False \ No newline at end of file + self._calculating_accuracy = False + + def _is_chinese_text_start(self, index: int) -> bool: + """ + 判断指定位置是否是中文文本的开始 + - 检查当前字符是否为中文 + - 检查前一个字符是否为非中文或空格 + """ + if index < 0 or index >= len(self.learning_content): + return False + + current_char = self.learning_content[index] + + # 检查当前字符是否为中文 + if not self._is_chinese_char(current_char): + return False + + # 如果是第一个字符,或者是紧跟在非中文字符后的中文,则认为是中文文本的开始 + if index == 0: + return True + + prev_char = self.learning_content[index - 1] + return not self._is_chinese_char(prev_char) or prev_char.isspace() + + def _is_chinese_char(self, char: str) -> bool: + """ + 判断字符是否为中文 + - 使用Unicode范围判断中文字符 + """ + return '\u4e00' <= char <= '\u9fff' or '\u3400' <= char <= '\u4dbf' + + def _get_chinese_word_at(self, index: int) -> str: + """ + 获取指定位置开始的中文词组 + - 从当前位置开始,连续获取中文字符 + - 遇到非中文字符或字符串结束则停止 + """ + if index < 0 or index >= len(self.learning_content): + return "" + + word = "" + current_index = index + + while current_index < len(self.learning_content): + char = self.learning_content[current_index] + if self._is_chinese_char(char): + word += char + current_index += 1 + else: + break + + return word + + def _calculate_errors_with_chinese_support(self, user_text: str) -> None: + """ + 使用中文整词匹配优化错误计算 + - 优先尝试中文整词匹配 + - 整词匹配失败时回退到逐字符匹配 + """ + i = 0 + while i < min(len(user_text), len(self.learning_content)): + # 检查当前位置是否为中文文本开始 + if self._is_chinese_text_start(i): + # 获取期望的中文词组 + expected_word = self._get_chinese_word_at(i) + # 获取用户输入的对应部分 + user_word = user_text[i:min(i + len(expected_word), len(user_text))] + + # 如果整词匹配成功,跳过整个词组 + if user_word == expected_word: + i += len(expected_word) + continue + else: + # 整词匹配失败,回退到逐字符匹配 + if user_text[i] != self.learning_content[i]: + self.error_count += 1 + else: + # 非中文文本,使用逐字符匹配 + if user_text[i] != self.learning_content[i]: + self.error_count += 1 + + i += 1 \ No newline at end of file diff --git a/src/ui/word_style_ui.py b/src/ui/word_style_ui.py index 0716239..9f5e03f 100644 --- a/src/ui/word_style_ui.py +++ b/src/ui/word_style_ui.py @@ -5,7 +5,7 @@ from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, QComboBox, QSpinBox, QFontComboBox, QToolBar, QSizePolicy) from PyQt5.QtCore import Qt, QSize -from PyQt5.QtGui import QFont, QIcon, QPalette, QColor +from PyQt5.QtGui import QFont, QIcon, QPalette, QColor, QInputMethodEvent import requests import json from datetime import datetime @@ -502,6 +502,48 @@ class WordTextEdit(QTextEdit): # 让父类处理实际的文本编辑逻辑 super().keyPressEvent(event) + def inputMethodEvent(self, event): + """重写输入法事件处理,支持中文输入法""" + if event.type() == QInputMethodEvent.InputMethod: + # 获取输入法事件中的文本 + commit_string = event.commitString() + preedit_string = event.preeditString() + + # 处理提交的文本(用户选择了候选词) + if commit_string: + if self.input_processor: + # 使用新的process_text_commit方法处理完整的提交文本 + self.input_processor.process_text_commit(commit_string) + + # 让父类处理实际的文本插入 + super().inputMethodEvent(event) + + # 触发文本变化信号,让学习模式能够处理 + self.textChanged.emit() + + # 处理预编辑文本(用户正在输入拼音) + elif preedit_string: + # 在预编辑阶段,我们只显示预编辑文本,不传递给输入处理器 + # 这样可以避免在学习模式下出现错误的匹配 + super().inputMethodEvent(event) + else: + # 其他情况,使用默认处理 + super().inputMethodEvent(event) + else: + # 非输入法事件,使用默认处理 + super().inputMethodEvent(event) + + def inputMethodQuery(self, query): + """重写输入法查询,提供更好的输入法支持""" + if query == Qt.ImEnabled: + return True # 启用输入法支持 + elif query == Qt.ImCursorRectangle: + # 返回光标位置,帮助输入法定位候选词窗口 + cursor_rect = self.cursorRect() + return cursor_rect + else: + return super().inputMethodQuery(query) + def setup_ui(self): """设置文本编辑区域样式""" self.setStyleSheet(""" diff --git a/src/word_main_window.py b/src/word_main_window.py index dbf3ffc..0891984 100644 --- a/src/word_main_window.py +++ b/src/word_main_window.py @@ -646,15 +646,21 @@ class WordStyleMainWindow(QMainWindow): cursor.movePosition(cursor.End) self.text_edit.setTextCursor(cursor) - # 更新打字逻辑(只检查已显示的部分) + # 更新打字逻辑(支持中文整词匹配) if display_text: result = self.typing_logic.check_input(display_text) self.typing_logic.update_position(display_text) - # 错误处理 + # 错误处理(支持中文整词显示) if not result['correct'] and display_text: expected_char = result.get('expected', '') - self.status_bar.showMessage(f"输入错误,期望字符: '{expected_char}'", 2000) + # 如果是中文文本,显示更友好的错误信息 + if self.typing_logic._is_chinese_char(expected_char): + # 获取期望的中文词组 + expected_word = self.typing_logic._get_chinese_word_at(result['position']) + self.status_bar.showMessage(f"输入错误,期望词组: '{expected_word}'", 3000) + else: + self.status_bar.showMessage(f"输入错误,期望字符: '{expected_char}'", 2000) self.highlight_next_char(result['position'], expected_char) # 更新统计信息 @@ -747,10 +753,16 @@ class WordStyleMainWindow(QMainWindow): result = self.typing_logic.check_input(current_text) self.typing_logic.update_position(current_text) - # 错误处理 + # 错误处理(支持中文整词显示) if not result['correct']: expected_char = result.get('expected', '') - self.status_bar.showMessage(f"输入错误,期望字符: '{expected_char}'", 2000) + # 如果是中文文本,显示更友好的错误信息 + if self.typing_logic._is_chinese_char(expected_char): + # 获取期望的中文词组 + expected_word = self.typing_logic._get_chinese_word_at(result['position']) + self.status_bar.showMessage(f"输入错误,期望词组: '{expected_word}'", 3000) + else: + self.status_bar.showMessage(f"输入错误,期望字符: '{expected_char}'", 2000) self.highlight_next_char(result['position'], expected_char) # 更新统计信息 @@ -766,10 +778,16 @@ class WordStyleMainWindow(QMainWindow): result = self.typing_logic.check_input(current_text) self.typing_logic.update_position(current_text) - # 错误处理 + # 错误处理(支持中文整词显示) if not result['correct']: expected_char = result.get('expected', '') - self.status_bar.showMessage(f"输入错误,期望字符: '{expected_char}'", 2000) + # 如果是中文文本,显示更友好的错误信息 + if self.typing_logic._is_chinese_char(expected_char): + # 获取期望的中文词组 + expected_word = self.typing_logic._get_chinese_word_at(result['position']) + self.status_bar.showMessage(f"输入错误,期望词组: '{expected_word}'", 3000) + else: + self.status_bar.showMessage(f"输入错误,期望字符: '{expected_char}'", 2000) self.highlight_next_char(result['position'], expected_char) # 更新统计信息 @@ -842,10 +860,16 @@ class WordStyleMainWindow(QMainWindow): result = self.typing_logic.check_input(display_text) self.typing_logic.update_position(display_text) - # 错误处理 + # 错误处理(支持中文整词显示) if not result['correct'] and display_text: expected_char = result.get('expected', '') - self.status_bar.showMessage(f"输入错误,期望字符: '{expected_char}'", 2000) + # 如果是中文文本,显示更友好的错误信息 + if self.typing_logic._is_chinese_char(expected_char): + # 获取期望的中文词组 + expected_word = self.typing_logic._get_chinese_word_at(result['position']) + self.status_bar.showMessage(f"输入错误,期望词组: '{expected_word}'", 3000) + else: + self.status_bar.showMessage(f"输入错误,期望字符: '{expected_char}'", 2000) self.highlight_next_char(result['position'], expected_char) # 更新统计信息