How to highlight a words in QTableWidget from a Searchlist











up vote
1
down vote

favorite
1












I want to search a QTableWidget-Table by a list of words, if they've been found i want them to bee highlighted.



I tried to modify the code from here so the table is beeing searched by a list of words, not just one. Unfortunatly my results keep getting overwritten. I always only get the result for the last word in the list.



Does anyone know how to modify the code so it will show the result of the whole list of words ?



Here is the code:



from PyQt5 import QtCore, QtGui, QtWidgets
import random
import html

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

class HTMLDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, parent=None):
super(HTMLDelegate, self).__init__(parent)
self.doc = QtGui.QTextDocument(self)

def paint(self, painter, option, index):
substring = index.data(QtCore.Qt.UserRole)
painter.save()
options = QtWidgets.QStyleOptionViewItem(option)
self.initStyleOption(options, index)
res = ""
color = QtGui.QColor("red")
if substring:
substrings = options.text.split(substring)
res = """<font color="{}">{}</font>""".format(color.name(QtGui.QColor.HexRgb), substring).join(list(map(html.escape, substrings)))
else:
res = html.escape(options.text)
self.doc.setHtml(res)

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()


class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
hlay = QtWidgets.QHBoxLayout()
lay = QtWidgets.QVBoxLayout(self)
self.table = QtWidgets.QTableWidget(5, 5)
lay.addLayout(hlay)
lay.addWidget(self.table)



self.table.setItemDelegate(HTMLDelegate(self.table))

for i in range(self.table.rowCount()):
for j in range(self.table.columnCount()):
it = QtWidgets.QTableWidgetItem(random.choice(words_1))
self.table.setItem(i, j, it)


text_list = ['ello', 'ack']
# clear
allitems = self.table.findItems("", QtCore.Qt.MatchContains)

selected_items =
for words in text_list:
for item in allitems:
selected_items = self.table.findItems(words, QtCore.Qt.MatchContains)
selected_items.append(self.table.findItems(words, QtCore.Qt.MatchContains)) ## i tried to make a list which is beeing appened but using this list it returns only the same as the input

item.setData(QtCore.Qt.UserRole, words if item in selected_items else None)




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









share|improve this question




























    up vote
    1
    down vote

    favorite
    1












    I want to search a QTableWidget-Table by a list of words, if they've been found i want them to bee highlighted.



    I tried to modify the code from here so the table is beeing searched by a list of words, not just one. Unfortunatly my results keep getting overwritten. I always only get the result for the last word in the list.



    Does anyone know how to modify the code so it will show the result of the whole list of words ?



    Here is the code:



    from PyQt5 import QtCore, QtGui, QtWidgets
    import random
    import html

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

    class HTMLDelegate(QtWidgets.QStyledItemDelegate):
    def __init__(self, parent=None):
    super(HTMLDelegate, self).__init__(parent)
    self.doc = QtGui.QTextDocument(self)

    def paint(self, painter, option, index):
    substring = index.data(QtCore.Qt.UserRole)
    painter.save()
    options = QtWidgets.QStyleOptionViewItem(option)
    self.initStyleOption(options, index)
    res = ""
    color = QtGui.QColor("red")
    if substring:
    substrings = options.text.split(substring)
    res = """<font color="{}">{}</font>""".format(color.name(QtGui.QColor.HexRgb), substring).join(list(map(html.escape, substrings)))
    else:
    res = html.escape(options.text)
    self.doc.setHtml(res)

    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()


    class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
    super(Widget, self).__init__(parent)
    hlay = QtWidgets.QHBoxLayout()
    lay = QtWidgets.QVBoxLayout(self)
    self.table = QtWidgets.QTableWidget(5, 5)
    lay.addLayout(hlay)
    lay.addWidget(self.table)



    self.table.setItemDelegate(HTMLDelegate(self.table))

    for i in range(self.table.rowCount()):
    for j in range(self.table.columnCount()):
    it = QtWidgets.QTableWidgetItem(random.choice(words_1))
    self.table.setItem(i, j, it)


    text_list = ['ello', 'ack']
    # clear
    allitems = self.table.findItems("", QtCore.Qt.MatchContains)

    selected_items =
    for words in text_list:
    for item in allitems:
    selected_items = self.table.findItems(words, QtCore.Qt.MatchContains)
    selected_items.append(self.table.findItems(words, QtCore.Qt.MatchContains)) ## i tried to make a list which is beeing appened but using this list it returns only the same as the input

    item.setData(QtCore.Qt.UserRole, words if item in selected_items else None)




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









    share|improve this question


























      up vote
      1
      down vote

      favorite
      1









      up vote
      1
      down vote

      favorite
      1






      1





      I want to search a QTableWidget-Table by a list of words, if they've been found i want them to bee highlighted.



      I tried to modify the code from here so the table is beeing searched by a list of words, not just one. Unfortunatly my results keep getting overwritten. I always only get the result for the last word in the list.



      Does anyone know how to modify the code so it will show the result of the whole list of words ?



      Here is the code:



      from PyQt5 import QtCore, QtGui, QtWidgets
      import random
      import html

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

      class HTMLDelegate(QtWidgets.QStyledItemDelegate):
      def __init__(self, parent=None):
      super(HTMLDelegate, self).__init__(parent)
      self.doc = QtGui.QTextDocument(self)

      def paint(self, painter, option, index):
      substring = index.data(QtCore.Qt.UserRole)
      painter.save()
      options = QtWidgets.QStyleOptionViewItem(option)
      self.initStyleOption(options, index)
      res = ""
      color = QtGui.QColor("red")
      if substring:
      substrings = options.text.split(substring)
      res = """<font color="{}">{}</font>""".format(color.name(QtGui.QColor.HexRgb), substring).join(list(map(html.escape, substrings)))
      else:
      res = html.escape(options.text)
      self.doc.setHtml(res)

      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()


      class Widget(QtWidgets.QWidget):
      def __init__(self, parent=None):
      super(Widget, self).__init__(parent)
      hlay = QtWidgets.QHBoxLayout()
      lay = QtWidgets.QVBoxLayout(self)
      self.table = QtWidgets.QTableWidget(5, 5)
      lay.addLayout(hlay)
      lay.addWidget(self.table)



      self.table.setItemDelegate(HTMLDelegate(self.table))

      for i in range(self.table.rowCount()):
      for j in range(self.table.columnCount()):
      it = QtWidgets.QTableWidgetItem(random.choice(words_1))
      self.table.setItem(i, j, it)


      text_list = ['ello', 'ack']
      # clear
      allitems = self.table.findItems("", QtCore.Qt.MatchContains)

      selected_items =
      for words in text_list:
      for item in allitems:
      selected_items = self.table.findItems(words, QtCore.Qt.MatchContains)
      selected_items.append(self.table.findItems(words, QtCore.Qt.MatchContains)) ## i tried to make a list which is beeing appened but using this list it returns only the same as the input

      item.setData(QtCore.Qt.UserRole, words if item in selected_items else None)




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









      share|improve this question















      I want to search a QTableWidget-Table by a list of words, if they've been found i want them to bee highlighted.



      I tried to modify the code from here so the table is beeing searched by a list of words, not just one. Unfortunatly my results keep getting overwritten. I always only get the result for the last word in the list.



      Does anyone know how to modify the code so it will show the result of the whole list of words ?



      Here is the code:



      from PyQt5 import QtCore, QtGui, QtWidgets
      import random
      import html

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

      class HTMLDelegate(QtWidgets.QStyledItemDelegate):
      def __init__(self, parent=None):
      super(HTMLDelegate, self).__init__(parent)
      self.doc = QtGui.QTextDocument(self)

      def paint(self, painter, option, index):
      substring = index.data(QtCore.Qt.UserRole)
      painter.save()
      options = QtWidgets.QStyleOptionViewItem(option)
      self.initStyleOption(options, index)
      res = ""
      color = QtGui.QColor("red")
      if substring:
      substrings = options.text.split(substring)
      res = """<font color="{}">{}</font>""".format(color.name(QtGui.QColor.HexRgb), substring).join(list(map(html.escape, substrings)))
      else:
      res = html.escape(options.text)
      self.doc.setHtml(res)

      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()


      class Widget(QtWidgets.QWidget):
      def __init__(self, parent=None):
      super(Widget, self).__init__(parent)
      hlay = QtWidgets.QHBoxLayout()
      lay = QtWidgets.QVBoxLayout(self)
      self.table = QtWidgets.QTableWidget(5, 5)
      lay.addLayout(hlay)
      lay.addWidget(self.table)



      self.table.setItemDelegate(HTMLDelegate(self.table))

      for i in range(self.table.rowCount()):
      for j in range(self.table.columnCount()):
      it = QtWidgets.QTableWidgetItem(random.choice(words_1))
      self.table.setItem(i, j, it)


      text_list = ['ello', 'ack']
      # clear
      allitems = self.table.findItems("", QtCore.Qt.MatchContains)

      selected_items =
      for words in text_list:
      for item in allitems:
      selected_items = self.table.findItems(words, QtCore.Qt.MatchContains)
      selected_items.append(self.table.findItems(words, QtCore.Qt.MatchContains)) ## i tried to make a list which is beeing appened but using this list it returns only the same as the input

      item.setData(QtCore.Qt.UserRole, words if item in selected_items else None)




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






      python pyqt pyqt5 qtablewidget






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 17 at 23:49









      eyllanesc

      68.4k92952




      68.4k92952










      asked Nov 17 at 16:59









      Mady

      315




      315
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          In the previous case I wanted to filter the cases so as not to have to paint unnecessarily but in this case because it was more complex I decided to implement the highlight logic using QTextCharFormat and not HTML as I show below:



          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.QVBoxLayout(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_())


          enter image description here






          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














             

            draft saved


            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53353450%2fhow-to-highlight-a-words-in-qtablewidget-from-a-searchlist%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote



            accepted










            In the previous case I wanted to filter the cases so as not to have to paint unnecessarily but in this case because it was more complex I decided to implement the highlight logic using QTextCharFormat and not HTML as I show below:



            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.QVBoxLayout(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_())


            enter image description here






            share|improve this answer

























              up vote
              2
              down vote



              accepted










              In the previous case I wanted to filter the cases so as not to have to paint unnecessarily but in this case because it was more complex I decided to implement the highlight logic using QTextCharFormat and not HTML as I show below:



              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.QVBoxLayout(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_())


              enter image description here






              share|improve this answer























                up vote
                2
                down vote



                accepted







                up vote
                2
                down vote



                accepted






                In the previous case I wanted to filter the cases so as not to have to paint unnecessarily but in this case because it was more complex I decided to implement the highlight logic using QTextCharFormat and not HTML as I show below:



                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.QVBoxLayout(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_())


                enter image description here






                share|improve this answer












                In the previous case I wanted to filter the cases so as not to have to paint unnecessarily but in this case because it was more complex I decided to implement the highlight logic using QTextCharFormat and not HTML as I show below:



                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.QVBoxLayout(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_())


                enter image description here







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 18 at 1:18









                eyllanesc

                68.4k92952




                68.4k92952






























                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53353450%2fhow-to-highlight-a-words-in-qtablewidget-from-a-searchlist%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Create new schema in PostgreSQL using DBeaver

                    Deepest pit of an array with Javascript: test on Codility

                    Costa Masnaga