【问题标题】:Pyqt Change color of one word in TableViewPyqt改变TableView中一个单词的颜色
【发布时间】:2016-03-28 10:03:23
【问题描述】:

我需要帮助更改 QTableView 中一个单词的颜色。

我需要做的是:当我在表中打开 csv 文件时,现在我的列~行中有句子/单词,我需要为一些单词着色,例如:

在这里你可以看到我的程序和我的 csv。 http://i.imgur.com/uIBQ2ch.jpg

示例:在 [3][0](4 行 1 列)中,您可以在我的图像中看到“filme”一词。

我想给这个词上色,如果存在相同的词,在 [3][2](4 行,3 列)我也想给这个词上色。

这是我的完整代码:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import sip
sip.setapi('QVariant', 2)
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import csv


try:
    _fromUtf8 = QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s:s



class MyWindow(QWidget):
def __init__(self, fileName, parent=None):
    super(MyWindow, self).__init__(parent)
    self.fileName = fileName

    self.model = QStandardItemModel(self)

    self.tableView = QTableView(self)
    self.tableView.setModel(self.model)
    self.tableView.horizontalHeader().setStretchLastSection(True)

    self.pushButtonLoad = QPushButton(self)
    self.pushButtonLoad.setText("Load Csv File!")
    self.pushButtonLoad.clicked.connect(self.on_pushButtonLoad_clicked)

    self.pushButtonWrite = QPushButton(self)
    self.pushButtonWrite.setText("Write Csv File!")
    self.pushButtonWrite.setStyleSheet('color:red;background-color:rgb(155, 255, 153);border:1px solid purple;')
    self.pushButtonWrite.clicked.connect(self.on_pushButtonWrite_clicked)

    self.layoutVertical = QVBoxLayout(self)
    self.layoutVertical.addWidget(self.tableView)
    self.layoutVertical.addWidget(self.pushButtonLoad)
    self.layoutVertical.addWidget(self.pushButtonWrite)


def loadCsv(self, fileName):
    with open(fileName, "rb") as fileInput:
        for row in csv.reader(fileInput):    
            items = [
                QStandardItem(field.decode('utf8'))
                for field in row
            ]
            self.model.appendRow(items)
            self.tableView.resizeRowsToContents()
            self.model.setHeaderData(0, Qt.Horizontal, "Feature")
            self.model.setHeaderData(1, Qt.Horizontal, "Polarity(-1,0,1)")
            self.model.setHeaderData(2, Qt.Horizontal, "texto")
            self.tableView.setColumnWidth(2,1000)
            self.tableView.resizeRowsToContents() 

def writeCsv(self, fileName):
    with open(fileName, "w") as fileOutput:
        writer = csv.writer(fileOutput)
        for rowNumber in range(self.model.rowCount()):
            fields = [
                self.model.data(
                    self.model.index(rowNumber, columnNumber),
                    Qt.DisplayRole
                )
                for columnNumber in range(self.model.columnCount())
            ]
            writer.writerow(fields)
@pyqtSlot()
def on_pushButtonWrite_clicked(self):
    self.writeCsv(self.fileName)

@pyqtSlot()
def on_pushButtonLoad_clicked(self):
    self.loadCsv(self.fileName)

if __name__ == "__main__":
import sys

app = QApplication(sys.argv)
app.setApplicationName('MyWindow')

main = MyWindow("marcoteste.csv")  

main.show()

sys.exit(app.exec_())

【问题讨论】:

    标签: python qt colors pyqt tableview


    【解决方案1】:

    据我所知,实际上有两种方法

    第一个就像 Oleg 说的,使用委托,但是我的实现有点笨,这是伪代码

    self.table = QTableView()
    self.model = QStandItemModel()
    self.table.setMode(model)
    self.table.pressed.connect(self.detectWord)
    
    def detectWord(self):
        self.to_color = []
        for row in range(self.model.rowCount()):
            for column in range(self.model.colunCount()):
                raw = self.model.data(self.model.index(row, column), Qt.DisplayRole)
                # needs decode, it's QString/utf-16 by default
                if 'word' in codecs.decode(raw.toString(), 'utf-16'):
                    self.to_color.append([row, column])
                    
        # apply delegate
        self.table.setItemDelegate(ColorColumn(self.to_color, self)
    
    class ColorColumn(QItemDelegate):
        def __init__(self, to_color, parent = None):
            self.to_color = to_color
            
        def paint(self, painter, option, index):
            masked = False
            for pos in self.to_delete:
                if index.row() == pos[0] and index.column == pos[1]:
                    text = index.model().data(index).toString()
                    palette = QApplication.palette()
                    
                    document = QTextDocument()
                    document.setDefaultFont(option.font)
                    document.setPlainText(text)
                    painter.save()
                    palette.fillRect(option.rect, QColor(255, 255, 0, 50))
                    document.drawContent(painter)
                    painter.restore()
                    masked = True
            
            if not masked:
                QItemDelegate.paint(self, paint, option, index)
    

    但这会以某种方式一次又一次地扫描整个数据,导致潜在的性能问题

    第二种比较标准,使用QAbstractTableModel,见shuman's answer

    基本上做以下事情

    1. 创建一个类来表示一个数据条目(继承对象)

      另外,def contains(self, column, to_color_word) 表示是否应该着色

    2. 创建一个模型来表示表(继承 QAbstractTableModel)

      和他一样,在data(self, index, role)中,意思是'read'或者model,在backgroundrole,使用你上面定义的方法来表示颜色

    3. setModel 在顶层组合

    这比使用QstandardItem更合适

    【讨论】:

      【解决方案2】:

      我对 Python 了解不多,但这里有一个想法。解决方案是为column of QTableView 使用自定义委托,并通过富文本支持实现其paint() 方法。在委托的 paint() 逻辑中,在显示之前将您的关键字包装成 HTML 标记,如 <font color="red">keyword</font>

      您可以找到示例 C++ 代码here

      【讨论】:

        猜你喜欢
        • 2013-03-15
        • 2018-02-14
        • 1970-01-01
        • 2011-11-05
        • 2014-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多