【问题标题】:QT - Is it possible to color half of a cell in a QTableView?QT - 是否可以在 QTableView 中为单元格的一半着色?
【发布时间】:2017-07-27 18:29:34
【问题描述】:

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

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

【问题讨论】:

  • 您可以创建一个自定义小部件,实现其绘制事件以呈现任何内容,然后使用 QTreeView::setIndexWidget() 将其添加到特定模型索引。但是,这可能会很慢,具体取决于您要添加到树中的数量。或者,您可以查看 QAbstractItemDelegate 类或其任何可用于为单元格提供自定义呈现的派生类 (doc.qt.io/qt-5/qabstractitemdelegate.html)。正如您所怀疑的那样,您实现了绘制委托功能并使用提供的模型索引来渲染您喜欢的任何东西! (参见 QTreeView::setItemDelegate())。
  • 我认为您可以在自定义委托的覆盖 QAbstractItemDelegate::paint() 函数中随意绘制整个单元格。

标签: qt delegates qtableview


【解决方案1】:

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

这是一个如何通过自定义委托在 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()

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

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

这是最终结果:

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

【讨论】:

  • 我应该更具体一点,我正在使用基于 QT5.8.0 的 QT creator 4.3 我感谢您的回答,它正在完成我想要的,但是我不熟悉您的代码语法。我正在使用 C++。你的代码是用什么写的?我从来没有见过像这样没有分号的导入或代码。
  • 它是带有 Qt 5 绑定的 Python,PyQt5。不幸的是,我手头没有电脑的情况被困了几天,所以虽然我可以将它翻译成 C++,但我只能在 2-3 天内完成。或者您可以按照解释的逻辑尝试自己做。
  • @JeffWilliams,我刚刚在答案底部添加了link 到 C++ 版本,请查看。
  • 非常感谢。我今天将尝试实现这一点,并让你知道它是如何进行的。
猜你喜欢
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-28
  • 2019-09-12
  • 2013-04-23
相关资源
最近更新 更多