【问题标题】:Highlight specific words in a QTableWidget cell in PYQT5 [duplicate]突出显示 PYQT5 中 QTableWidget 单元格中的特定单词 [重复]
【发布时间】:2021-01-22 04:53:58
【问题描述】:

我需要一些关于如何在 QTableWidget 单元格中突出显示特定单词的帮助。例如在这张图片中。假设我想突出显示 "James" 字样的绿色。有些词 “James” 是完整的词,而那些不是那么静止的词我需要突出显示

现在请注意,我已经对此进行了搜索,并找到了类似的解决方案并对其进行了研究(实际上很酷!)。 How to highlight a words in QTableWidget from a Searchlist。但似乎有些部分与我的目标不同,而且非常复杂,而我的目标非常简单。就像表格有数据时它会突出显示一个选定的单词一样,我相信这可以通过更短的代码或更简单的方式轻松完成,以实现单词的着色。请我需要一些帮助,我觉得这真的很棒,并期待完成。

让我们用这个示例代码和一个简单的 PYQT5 QTableWidget 进行测试。

import sys 
from PyQt5.QtWidgets import * 
                    
   
#Main Window 
class App(QWidget): 
    def __init__(self): 
        super().__init__() 
        self.title = 'PyQt5 - QTableWidget'
        self.left = 0
        self.top = 0
        self.width = 300
        self.height = 200
   
        self.setWindowTitle(self.title) 
        self.setGeometry(self.left, self.top, self.width, self.height) 
   
        self.createTable() 
   
        self.layout = QVBoxLayout() 
        self.layout.addWidget(self.tableWidget) 
        self.setLayout(self.layout) 
   
        #Show window 
        self.show() 
   
    #Create table 
    def createTable(self): 
        self.tableWidget = QTableWidget() 
  
        #Row count 
        self.tableWidget.setRowCount(4)  
  
        #Column count 
        self.tableWidget.setColumnCount(2)   
  
        self.tableWidget.setItem(0,0, QTableWidgetItem("Name")) 
        self.tableWidget.setItem(0,1, QTableWidgetItem("City")) 
        self.tableWidget.setItem(1,0, QTableWidgetItem("Lebron James")) 
        self.tableWidget.setItem(1,1, QTableWidgetItem("King James")) 
        self.tableWidget.setItem(2,0, QTableWidgetItem("KingJames")) 
        self.tableWidget.setItem(2,1, QTableWidgetItem("Champions")) 
        self.tableWidget.setItem(3,0, QTableWidgetItem("World")) 
        self.tableWidget.setItem(3,1, QTableWidgetItem("2020")) 
   
        #Table will fit the screen horizontally 
        self.tableWidget.horizontalHeader().setStretchLastSection(True) 
        self.tableWidget.horizontalHeader().setSectionResizeMode( 
            QHeaderView.Stretch) 
   
if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    ex = App() 
    sys.exit(app.exec_()) 

【问题讨论】:

  • 您的情况与其他问题的情况有何不同?
  • 我想知道是否有更简单的方法来做到这一点......因为我要修改它,而且我还有一些条件需要考虑换句话......有了这个我就可以实现我自己的一些......我现在仍在尝试基于另一个答案,但我希望会有另一个答案。
  • 我可以发布这个问题的答案吗?
  • 当然可以,只要它是您问题的有效答案。

标签: python python-3.x user-interface pyqt pyqt5


【解决方案1】:

从类似答案中研究代码非常具有挑战性,但我设法弄清楚了,这里是代码。我唯一仍然好奇的是,是否有一种更简单的方法可以做到这一点,因为我一直在研究代码并思考真正发生的事情以及所有这些必要的事情。但无论如何,如果没有,我将继续从这个answer 实施解决方案。谢谢!

import sys, re
from PyQt5.QtWidgets import * 
from PyQt5 import QtCore, QtGui, QtWidgets
   
#Main Window 
class App(QWidget): 
    def __init__(self): 
        super().__init__() 
        self.title = 'PyQt5 - QTableWidget'
        self.left = 0
        self.top = 0
        self.width = 300
        self.height = 200
   
        self.setWindowTitle(self.title) 
        self.setGeometry(self.left, self.top, self.width, self.height) 
   
        self.createTable() 
   
        self.layout = QVBoxLayout() 
        self.layout.addWidget(self.tableWidget) 
        self.setLayout(self.layout) 
   
        #Show window 
        self.show() 
   
    #Create table 
    def createTable(self): 
        self.tableWidget = QTableWidget() 
        self._delegate = HighlightDelegate(self.tableWidget)
        self.tableWidget.setItemDelegate(self._delegate)
  
        #Row count 
        self.tableWidget.setRowCount(4)  
  
        #Column count 
        self.tableWidget.setColumnCount(2)   
  
        self.tableWidget.setItem(0,0, QTableWidgetItem("Name")) 
        self.tableWidget.setItem(0,1, QTableWidgetItem("City")) 
        self.tableWidget.setItem(1,0, QTableWidgetItem("Lebron James")) 
        self.tableWidget.setItem(1,1, QTableWidgetItem("King James")) 
        self.tableWidget.setItem(2,0, QTableWidgetItem("KingJames")) 
        self.tableWidget.setItem(2,1, QTableWidgetItem("Champions")) 
        self.tableWidget.setItem(3,0, QTableWidgetItem("World")) 
        self.tableWidget.setItem(3,1, QTableWidgetItem("2020")) 
   
        #Table will fit the screen horizontally 
        self.tableWidget.horizontalHeader().setStretchLastSection(True) 
        self.tableWidget.horizontalHeader().setSectionResizeMode( 
            QHeaderView.Stretch) 

        #Started coloring
        self.on_textChanged()



    def on_textChanged(self, text="James"):
        self._delegate.setFilters(list(set(text.split())))
        self.tableWidget.viewport().update()












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)

        
        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,text):
        cursor = QtGui.QTextCursor(self.doc)
        cursor.beginEditBlock()
        fmt = QtGui.QTextCharFormat()

        highlight_word = ''.join(self.filters())
        print(text)
        sentence_status = re.search(r'\b'+ highlight_word + r'\b',text,re.IGNORECASE)

        if sentence_status != None:
            fmt.setForeground(QtCore.Qt.darkGreen)
        else:
            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



















if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    ex = App() 
    sys.exit(app.exec_()) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多