QT - 是否可以为 QTableView 中的一半单元格着色?

标签 qt delegates qtableview

我想如果可能的话,它会涉及重新实现实际将颜色绘制到单元格中的函数,或者创建某种委托(delegate)。

有人有这方面的经验吗?有可能吗?

最佳答案

是的,完全可以按照您想要的方式绘制 QTableView 的单元格。 Qt 足够灵活,可以做到这一点。

这是一个如何通过自定义委托(delegate)在 PyQt5 中完成的示例:

import sys
import string
import random
from PyQt5 import QtCore, QtWidgets, QtGui

class Delegate(QtWidgets.QStyledItemDelegate):
    def __init__(self):
        QtWidgets.QStyledItemDelegate.__init__(self)

    def paint(self, painter, option, index):
        painter.save()
        left_rect = QtCore.QRect(option.rect.left(), option.rect.top(),
                                 option.rect.width() / 2, option.rect.height())
        left_brush = QtGui.QBrush(QtCore.Qt.red)
        painter.fillRect(left_rect, left_brush)
        right_rect = QtCore.QRect(option.rect.left() + option.rect.width() / 2,
                                  option.rect.top(), option.rect.width() / 2,
                                  option.rect.height())
        right_brush = QtGui.QBrush(QtCore.Qt.blue)
        painter.fillRect(right_rect, right_brush)
        painter.restore()
        adjusted_option = option
        adjusted_option.backgroundBrush = QtGui.QBrush(QtCore.Qt.NoBrush)
        QtWidgets.QStyledItemDelegate.paint(self, painter, adjusted_option, index)

class Model(QtCore.QAbstractTableModel):
    def __init__(self):
        QtCore.QAbstractTableModel.__init__(self)
        self.column_names = [ "First",
                              "Second",
                              "Third",
                              "Fourth" ]
        self.text_data = []
        for i in range(0, 10):
            row_data = []
            for j in range(0, len(self.column_names)):
                row_data.append(''.join(random.choice(string.ascii_uppercase +
                                        string.digits) for _ in range(6)))
            self.text_data.append(row_data)

    def rowCount(self, parent):
        if parent.isValid():
            return 0
        else:
            return len(self.text_data)

    def columnCount(self, parent):
        return len(self.column_names)

    def data(self, index, role):
        if not index.isValid():
            return None
        if role != QtCore.Qt.DisplayRole:
            return None

        row = index.row()
        if row < 0 or row >= len(self.text_data):
            return None

        column = index.column()
        if column < 0 or column >= len(self.column_names):
            return None

        return self.text_data[row][column]

    def headerData(self, section, orientation, role):
        if role != QtCore.Qt.DisplayRole:
            return None
        if orientation != QtCore.Qt.Horizontal:
            return None
        if section < 0 or section >= len(self.column_names):
            return None
        else:
            return self.column_names[section]

class MainForm(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.model = Model()
        self.delegate = Delegate()
        self.view = QtWidgets.QTableView()
        self.view.setModel(self.model)
        self.view.setItemDelegate(self.delegate)
        self.setCentralWidget(self.view)

def main():
    app = QtWidgets.QApplication(sys.argv)
    form = MainForm()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()

基本上,我们实现一个自定义委托(delegate)作为 QStyledItemDelegate 的子类,并重新实现 paint 方法来执行以下操作:

  1. 用红色绘制左半边单元格的背景
  2. 用蓝色画出右半边单元格的背景
  3. 将其余绘画的背景画笔设置为“无画笔”,即防止进一步绘制背景
  4. 调用基类的绘画来绘制单元格背景以外的所有内容

这是最终结果:

result

更新。:这是翻译成 C++ 的相同代码的一个版本:Half-cell-delegate

关于QT - 是否可以为 QTableView 中的一半单元格着色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45358480/

相关文章:

constructor - F# 使用构造函数作为函数

python - 如何重新排列 QTableView 的列顺序

python - 如何编辑qtableview中的特定项目?

c++ - 如何从多个 std::threads 手动发送 QSignal?

c++ - 使用内置 MySQL 库静态构建 Qt

ios - 带有文本字段的 TableView 单元格

c++ - 如何在 QTableView 中打开一个 URL

c++ - QGraphicsView 是否拥有其关联图形场景的所有权?

c++ - 在不同的线程中执行每个QTModbus响应

ios - 弱委托(delegate)和类协议(protocol)