QTextDocument 的悬停效果

Hover effect for QTextDocument

我想在 QTextDocument 内的 p 标签上有一些悬停效果。

我尝试使用 QTextDocument().setDefaultStyleSheet()QTextDocument 设置 QSS。 这是我得到的结果;

脚本;

from PySide2 import QtWidgets


class Test(QtWidgets.QTextBrowser):
    def __init__(self):
        super().__init__()

        self.document().setDefaultStyleSheet(
            """
p.out{
    background-color: "orange";
    color: "black";
}

p.out:hover{
    background-color: "yellow";
}
"""
        )

        self.setStyleSheet(
            """
QTextBrowser{
    background-color: "black";
    color: "white";
}
""")

        self.setHtml(
            """
<p class='out'> Checking this </p>
"""
        )


test = QtWidgets.QApplication([])

sample = Test()
sample.show()

test.exec_()

qss 中的颜色属性有效,但悬停无效。

有什么方法可以在文档中的 文本片段 上实现悬停效果?

理解后,QTextDocument的structure and Syntax Highlighter. We can modify QTextBlock's Format随时都可以。我尝试使用 enterEvent 更改它的格式,并在 leaveEvent 中恢复格式。

我们可以使用QTextFrame using QTextFrameFormat修改盒子模型。

from PySide2 import QtWidgets, QtGui


class High(QtGui.QSyntaxHighlighter):
    def __init__(self, doc):
        super().__init__(doc)

        self._formats = tuple(
            QtGui.QTextCharFormat() for _ in range(2)
        )

        self._formats[1].setForeground(
            QtGui.QBrush(QtGui.QColor("orange"))
        )

        self._formats[1].setFontWeight(3)
        self._formats[1].setFontUnderline(True)
        self._formats[1].setFontPointSize(12)

    def highlightBlock(self, text: str):
        self.setFormat(
            0, len(text), self._formats[self.currentBlockState() if self.currentBlockState() > -1 else 0]
        )


class Sample(QtWidgets.QTextBrowser):
    def __init__(self):
        super().__init__()
        self.lighter = High(self.document())
        self._prev = None

        self.insertBlock("This is a sample line\n")
        self.insertBlock("Can also be a\nparagraph thing\n")
        self.insertBlock("it's a block, Bye!")

    def insertBlock(self, text):
        cur = self.textCursor()
        cur.block().setUserState(0)  # default: -1

        cur.insertText(text)

    def mouseMoveEvent(self, eve):
        super().mouseMoveEvent(eve)

        cur = self.cursorForPosition(eve.pos())

        if cur.block() == self._prev:
            return

        self.restore()
        cur.block().setUserState(1)
        self.lighter.rehighlightBlock(cur.block())

        self._prev = cur.block()

    def restore(self):
        if not self._prev:
            return

        self._prev.setUserState(0)
        self.lighter.rehighlightBlock(self._prev)
        self._prev = None

    def leaveEvent(self, eve):
        self.restore()
        super().leaveEvent(eve)


testing = QtWidgets.QApplication([])
sample = Sample()
sample.show()
testing.exec_()