为了账号安全,请及时绑定邮箱和手机立即绑定

为什么我的 charFormat 样式只适用于选择,而且只适用于特定方向的选择?

为什么我的 charFormat 样式只适用于选择,而且只适用于特定方向的选择?

红糖糍粑 2023-05-23 16:03:04
我一直在尝试更明确地分配文本编辑器的字符格式,以便我可以了解我可以根据当前的技能范围自定义哪些内容。虽然我的格式化方法的基本复制粘贴版本工作得很好,但下面的版本一直在工作,然后以令人沮丧的方式无法工作,需要帮助找出可能导致它的原因。该编辑器最初旨在成为通过文档标签设计样式的所见即所得编辑器。Qt 对 Html 的混乱使用并没有让事情变得如此简单。我的基本流程是提取当前格式的副本,检查其当前状态,反转它,然后将格式重新应用到从中提取的位置或选择。# textEdit is a QTextEdit with a loaded document.# This function is one of several related pairs called by a switchboard.# It's intent is to invert the italic state of the current position/selection.def toggle_italic_text(textEdit):    # Get the cursor, and the format's state at its current selection/position.    cursor = textEdit.textCursor()    charFormat = cursor.charFormat()    currentState = charFormat.fontItalic()    # Invert the state within the format.    print(currentState)    charFormat.setFontItalic(not currentState)    print(charFormat.fontItalic())    # Reapply the format to the cursor's current selection/position.    cursor.mergeCharFormat(charFormat)当我第一次实施它时,这很有效。现在,它只适用于选择,即便如此,它似乎也会根据我选择的方向来识别错误的状态。在试验之后,似乎如果我向右进行选择,它就会正确反转。如果我在左侧进行选择,则不会。当尝试将其分配到没有选择的位置时,打印状态从 False 变为 True,这是需要的,但效果在我键入时不适用。如果我就地重复运行它,它会继续从 False 变为 True,这意味着更改正在丢失。该函数被一致调用并完全运行。charFormat 副本的存储状态确实发生了变化。为什么这种模式停止工作了?我使用的 charFormats 错了吗?为什么选择的方向会改变结果?就我这边发生的变化而言,在需要通过 QFonts、QCharFormats、QPalette 和 CSS 样式表(以及 doc.defaultStylesheet)同时针对小部件和 html 标签来应用样式之后,我在样式设计工作中迷失了方向。我非常希望通过一种方法来控制我的样式,但无法弄清楚层次结构或找到一种应用足够广泛的方法。最后,除了分配给窗口的样式表之外,我删除了所有内容。如果代码本身没有问题,我真的希望能得到一些提示,说明什么可能会破坏事情。我花了一段时间才习惯这样的想法,即光标和格式是要更改和重新应用的副本,而文档及其块才是真正的结构。
查看完整描述

2 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

必须考虑的重要事项QTextCursor.charFormat()是:

返回光标position ( )之前字符的格式

因此,这不仅不能很好地处理包含多种字符格式的选择,而且您还必须考虑光标位置,它可能会在选择中发生变化:它可能在开头(因此它会返回格式选择之前的字符)或结尾(返回选择中最后一个字符的格式)。

如果要根据当前光标位置反转状态(如果在开头,则使用第一个字符,如果在结尾,则使用最后一个),则可以使用以下内容:


查看完整回答
反对 回复 2023-05-23
?
慕仙森

TA贡献1827条经验 获得超7个赞

    def toggle_italic_text(self):

        cursor = self.textEdit.textCursor()

        if not cursor.hasSelection():

            charFormat = cursor.charFormat()

            charFormat.setFontItalic(not charFormat.fontItalic())

            cursor.setCharFormat(charFormat)

            # in this case, the cursor has to be applied to the textEdit to ensure

            # that the following typed characters use the new format

            self.textEdit.setTextCursor(cursor)

            return


        start = cursor.selectionStart()

        end = cursor.selectionEnd()

        newCursor = QtGui.QTextCursor(self.textEdit.document())

        newCursor.setPosition(start)


        if cursor.position() == start:

            cursor.setPosition(start + 1)

        charFormat = cursor.charFormat()

        charFormat.setFontItalic(not charFormat.fontItalic())

        newCursor.setPosition(end, cursor.KeepAnchor)

        newCursor.mergeCharFormat(charFormat)

如果要反转选择中的所有状态,则需要循环遍历所有字符。

虽然您可以只更改每个字符的 char 格式,但这对于非常大的选择来说并不是一件好事,因此解决方案是仅在 char 格式实际从以前的状态发生变化时应用斜体,并且在选择结束。


    def toggle_italic_text(self):

        # ...

        start = cursor.selectionStart()

        end = cursor.selectionEnd()

        newCursor = QtGui.QTextCursor(self.textEdit.document())

        newCursor.setPosition(start)


        cursor.setPosition(start)

        prevState = cursor.charFormat().fontItalic()

        while cursor.position() < end:

            cursor.movePosition(cursor.Right)

            charFormat = cursor.charFormat()

            if charFormat.fontItalic() != prevState or cursor.position() >= end:

                newPos = cursor.position()

                if cursor.position() < end:

                    newPos -= 1

                newCursor.setPosition(newPos, cursor.KeepAnchor)

                charFormat.setFontItalic(not prevState)

                newCursor.mergeCharFormat(charFormat)

                prevState = not prevState

                newCursor.setPosition(cursor.position() - 1)


查看完整回答
反对 回复 2023-05-23
  • 2 回答
  • 0 关注
  • 70 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信