QTextEdit反向选中文本时字体粗细识别错误问题
QTextEdit反向选中文本时格式判断错误的解决方案
问题原因
QTextCursor的charFormat()方法默认返回光标插入点左侧字符的格式。当从右向左选中文本时,光标插入点会停在选区的起始位置(例如选中加粗文本"little"从右到左,光标会落在'l'的左侧,也就是前面普通文本的位置),此时拿到的是普通文本的格式,而非选区内加粗文本的格式,导致格式判断错误,无法正常切换加粗状态。
解决方案
方案1:基于选区首字符格式切换(简洁高效)
如果你的场景中选区内格式通常统一(全加粗或全正常),直接获取选区起始位置的字符格式来判断,彻底避免光标位置的影响:
def setBold(self): component = self.win.focusWidget() if isinstance(component, QTextEdit): cursor = component.textCursor() if cursor.hasSelection(): start_pos = cursor.selectionStart() # 创建临时光标获取选区第一个字符的格式 temp_cursor = QTextCursor(component.document()) temp_cursor.setPosition(start_pos) char_format = temp_cursor.charFormat() # 切换加粗状态 if char_format.font().bold(): char_format.setFontWeight(QFont.Normal) else: char_format.setFontWeight(QFont.Bold) # 将格式应用到整个选区 cursor.mergeCharFormat(char_format) component.setTextCursor(cursor) else: font = cursor.charFormat().font() if font.weight() == QFont.Normal: font.setWeight(QFont.Bold) component.setCurrentFont(font) else: font.setWeight(QFont.Normal) component.setCurrentFont(font)
方案2:遍历选区判断统一格式(适配混合格式场景)
如果选区内可能存在混合格式(部分加粗、部分正常),需要遍历判断所有选中字符是否都为加粗,再执行切换逻辑,符合主流编辑器的行为:
from PyQt5.QtGui import QTextCursor, QFont, QTextCharFormat def setBold(self): component = self.win.focusWidget() if isinstance(component, QTextEdit): cursor = component.textCursor() if cursor.hasSelection(): start = cursor.selectionStart() end = cursor.selectionEnd() # 遍历选区所有字符,判断是否全部加粗 temp_cursor = QTextCursor(component.document()) temp_cursor.setPosition(start) all_bold = True while temp_cursor.position() < end: fmt = temp_cursor.charFormat() if not fmt.font().bold(): all_bold = False break temp_cursor.movePosition(QTextCursor.NextCharacter) # 创建要应用的格式 target_format = QTextCharFormat() target_format.setFontWeight(QFont.Normal if all_bold else QFont.Bold) # 应用格式到整个选区 cursor.mergeCharFormat(target_format) component.setTextCursor(cursor) else: font = cursor.charFormat().font() if font.weight() == QFont.Normal: font.setWeight(QFont.Bold) component.setCurrentFont(font) else: font.setWeight(QFont.Normal) component.setCurrentFont(font)
方案说明
- 方案1代码简洁、执行高效,适合选区内格式统一的常规场景;
- 方案2逻辑更严谨,能处理选区内格式混合的情况:点击加粗按钮时,只有当所有选中字符都为加粗状态,才统一取消加粗;否则将所有选中字符设置为加粗。
内容的提问来源于stack exchange,提问作者Jeremy Wilson
相关产品推荐
相关产品推荐

