您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

如何从搜索列表中突出显示QTableWidget中的单词

如何从搜索列表中突出显示QTableWidget中的单词

在前一个案例中,我希望过滤案例以免不必要地绘制,但在这种情况下,由于情况更为复杂,我决定使用QTextCharFormat而不是HTML来实现高亮逻辑,如下所示:

from PyQt5 import QtCore, QtGui, QtWidgets
import random

words = ["Hello dseerfd", "world sdfsdf sdfgsdf sdfsdf", "Stack dasdf", "Overflow", "Hello world", """<font color="red">Hello world</font>"""]

class HighlightDelegate(QtWidgets.QStyledItemDelegate):
    def __init__(self, parent=None):
        super(HighlightDelegate, self).__init__(parent)
        self.doc = QtGui.QTextDocument(self)
        self._filters = []

    def paint(self, painter, option, index):
        painter.save()
        options = QtWidgets.QStyleOptionViewItem(option)
        self.initStyleOption(options, index)
        self.doc.setPlainText(options.text)
        self.apply_highlight()
        options.text = ""
        style = QtWidgets.QApplication.style() if options.widget is None \
            else options.widget.style()
        style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, options, painter)

        ctx = QtGui.QAbstractTextDocumentLayout.PaintContext()
        if option.state & QtWidgets.QStyle.State_Selected:
            ctx.palette.setColor(QtGui.QPalette.Text, option.palette.color(
                QtGui.QPalette.Active, QtGui.QPalette.HighlightedText))
        else:
            ctx.palette.setColor(QtGui.QPalette.Text, option.palette.color(
                QtGui.QPalette.Active, QtGui.QPalette.Text))

        textRect = style.subElementRect(
            QtWidgets.QStyle.SE_ItemViewItemText, options)

        if index.column() != 0:
            textRect.adjust(5, 0, 0, 0)

        the_constant = 4
        margin = (option.rect.height() - options.fontMetrics.height()) // 2
        margin = margin - the_constant
        textRect.setTop(textRect.top() + margin)

        painter.translate(textRect.topLeft())
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        self.doc.documentLayout().draw(painter, ctx)

        painter.restore()

    def apply_highlight(self):
        cursor = QtGui.QTextCursor(self.doc)
        cursor.beginEditBlock()
        fmt = QtGui.QTextCharFormat()
        fmt.setForeground(QtCore.Qt.red)
        for f in self.filters():
            highlightCursor = QtGui.QTextCursor(self.doc)
            while not highlightCursor.isNull() and not highlightCursor.atEnd():
                highlightCursor = self.doc.find(f, highlightCursor)
                if not highlightCursor.isNull():
                    highlightCursor.mergeCharFormat(fmt)
        cursor.endEditBlock()

    @QtCore.pyqtSlot(list)
    def setFilters(self, filters):
        if self._filters == filters: return
        self._filters = filters

    def filters(self):
        return self._filters

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)

        self.table = QtWidgets.QTableWidget(30, 6)
        self._delegate = HighlightDelegate(self.table)
        self.table.setItemDelegate(self._delegate)
        for i in range(self.table.rowCount()):
            for j in range(self.table.columnCount()):
                it = QtWidgets.QTableWidgetItem(random.choice(words))
                self.table.setItem(i, j, it)
        self.table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

        le = QtWidgets.QLineEdit()
        le.textChanged.connect(self.on_textChanged)
        lay = QtWidgets.QV@R_589_2419@Layout(self)
        lay.addWidget(le)
        lay.addWidget(self.table)

        le.setText("ello ack")

    @QtCore.pyqtSlot(str)
    def on_textChanged(self, text):
        self._delegate.setFilters(list(set(text.split())))
        self.table.viewport().update()

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.showMaximized()
    sys.exit(app.exec_())

在此处输入图片说明

其他 2022/1/1 18:33:56 有576人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶