You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 01:48:38