Semi-transparent highlights using PySide and QTextEdit

前端 未结 1 2066
醉酒成梦
醉酒成梦 2021-01-22 01:31

I\'ve created a QTextEdit object. The code below adds randomly colored highlights to the currently selected text. I need the highlights to be semi-transparent so I can see highl

相关标签:
1条回答
  • 2021-01-22 02:15

    It seems unlikely that QTextEdit would support anything as sophisticated as layered formatting. So I think you will have to do the blending of colours yourself. The example below uses a fairly crude method, but it seems to work okay. I'm not exactly sure what results you're aiming for, but it should give you some idea how to proceeed:

    import sys
    from random import sample
    from PySide import QtCore, QtGui
    
    class Window(QtGui.QWidget):
        def __init__(self):
            super(Window, self).__init__()
            self.button = QtGui.QPushButton('Highlight', self)
            self.button.clicked.connect(self.handleButton)
            self.edit = QtGui.QTextEdit(self)
            self.edit.setText(open(__file__).read())
            layout = QtGui.QVBoxLayout(self)
            layout.addWidget(self.edit)
            layout.addWidget(self.button)
    
        def blendColors(self, first, second, ratio=0.5, alpha=100):
            ratio2 = 1 - ratio
            return QtGui.QColor(
                (first.red() * ratio) + (second.red() * ratio2),
                (first.green() * ratio) + (second.green() * ratio2),
                (first.blue() * ratio) + (second.blue() * ratio2),
                alpha,
                )
    
        def handleButton(self):
            cursor = self.edit.textCursor()
            start = cursor.selectionStart()
            end = cursor.selectionEnd()
            if start != end:
                default = QtGui.QTextCharFormat().background().color()
                color = QtGui.QColor(*sample(range(0, 255), 3))
                color.setAlpha(100)
                for pos in range(start, end):
                    cursor.setPosition(pos)
                    cursor.movePosition(QtGui.QTextCursor.NextCharacter,
                                        QtGui.QTextCursor.KeepAnchor)
                    charfmt = cursor.charFormat()
                    current = charfmt.background().color()
                    if current != default:
                        charfmt.setBackground(self.blendColors(current, color))
                    else:
                        charfmt.setBackground(color)
                    cursor.setCharFormat(charfmt)
                cursor.clearSelection()
                self.edit.setTextCursor(cursor)
    
    if __name__ == '__main__':
    
        app = QtGui.QApplication(sys.argv)
        window = Window()
        window.setGeometry(800, 100, 600, 500)
        window.show()
        sys.exit(app.exec_())
    

    (PS: one thing I haven't attempted to implement here is removing highlights. If you used a relatively small set of colours, I suppose you could pre-compute a table of all colour combinations, and then use a key of (current_color, removed_color) to look up the required "subtracted" colour).

    0 讨论(0)
提交回复
热议问题