什么是“角色”及其来源? (如何在编辑QTableView单元格后更改背景颜色?)

时间:2013-11-30 09:16:37

标签: python pyqt qtableview

我试图在编辑后更改qtable单元格的背景颜色。我已经看过qustion“How to change background color after editing QTableView cell?”,我的问题是,在答案的例子中,我不明白“角色”来自哪里。我的意思是,角色在哪里声明,角色在哪里改变它的价值?我只看到角色与“Qt.Core.xxx”比较的地方

import sys
from PyQt4 import QtGui, QtCore

class Model(QtCore.QAbstractTableModel):
    def __init__(self, parent=None):
        super(Model, self).__init__(parent)

    # list of lists containing [data for cell, changed]
    self._data = [[['%d - %d' % (i, j), False] for j in range(10)] for i in range(10)]

    def rowCount(self, parent):
        return len(self._data)

    def columnCount(self, parent):
        return len(self._data[0])

    def flags(self, index):
        return QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled |QtCore.Qt.ItemIsEditable

    def data(self, index, role):
        if index.isValid():
            data, changed = self._data[index.row()][index.column()]

        if role in [QtCore.Qt.DisplayRole, QtCore.Qt.EditRole]:
            return data

        if role == QtCore.Qt.BackgroundRole and changed:
            return QtGui.QBrush(QtCore.Qt.darkBlue)

    def setData(self, index, value, role):
        if role == QtCore.Qt.EditRole:
            # set the new value with True `changed` status
            self._data[index.row()][index.column()] = [value.toString(), True]
            self.dataChanged.emit(index, index)
            return True
    return False

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)

t = QtGui.QTableView()
m = Model(t)
t.setModel(m)
t.show()

sys.exit(app.exec_())

我不能在另一个问题中添加评论,因为我没有50个“重点”,sry。

2 个答案:

答案 0 :(得分:3)

它是QAbstractItemModel接口的一部分。见:

如果您想了解有关Qt模型/视图(/ Controller)方法的更多信息,还有一个教程:

编辑(一点程序说明):

嗯,显然你创建了一个实现QAbstractTableModel,它有一个比QAbstractItemModel更专业的接口。它是“抽象的”,所以这意味着你必须提供一个有效的实现。另一方面,它已经实现了一些QAbstractItemModel方法,如createIndex()。在访问有关表的信息时,Qt会在内部使用您的模型实现。

最重要的方法是data()用于数据访问,setData()用于更改数据。您的数据是一对二维数组:[string, bool]。第一个元素是您在表格单元格中显示的文本,第二个元素是一个属性,用于保存该特定元素是否已更改的信息。

这些方法通常由Qt调用,例如当您编辑单元格时,将鼠标移到小部件等上。例如,如果将鼠标悬停在表格单元格上一会儿,Qt将调用data(cellIndex, QtCore.Qt.TooltipRole),这样您就可以显示工具提示文本。因此,在这种情况下,roles反映用户已采取的活动或操作。就像文档说:

  

模型中的每个项目都有一组与之关联的数据元素,每个元素都有自己的角色。视图使用这些角色向模型指示它需要哪种类型的数据。自定义模型应返回这些类型的数据。

您不必提供所有数据角色。您可以简单地在C ++中返回QVariant()或在Python中返回None(Python实际上不需要QVariant之类的内容,因为它是dynamically typed)。请记住,当您在Python中到达函数结尾并且不返回任何内容时,Python将默认返回None

还有flags()方法告诉Qt用户可以执行哪些操作。删除QtCore.Qt.ItemIsEditable,您将无法编辑您的表格。这里的一个小技巧是那些标志的int值是2的幂。这样它们可以很容易OR-ed(对不起,如果它不是正确的按位OR动词;))并返回一个整数。 / p>

因此,当你双击单元格时,Qt首先检查flags()。如果设置了QtCore.Qt.ItemIsEditable,则会将该单元格更改为可以键入新值的文本区域。如果你离开它(例如按Enter键或选择另一个单元格),它将在你的模型上调用setData(cellIndex, typedString, Qt.EditRole)。此外,setData()会发出一个信号,该信号会在数据发生更改时通知View,并且应该刷新它正在显示的数据。

这种方法为我们提供了数据控制器和数据查看器的分离。 Model不知道使用它的视图如何显示数据(可能有多个,并且它们将一直同步)。它被称为MVC - 模型/视图/控制器。不幸的是,Qt为其MVC实现命名是误导性的,但关于它,你可以阅读更多,例如here

嗯,这个反应有点太长了,但我希望这对你至少有一点帮助。祝好运! :)

答案 1 :(得分:0)

角色是您自己或Qt内部使用的ID,用于访问给定数据的表示或元数据。例如,如果您的数据是一种颜色,则此颜色可以表示为字符串(颜色的名称)或颜色本身(例如#123456)。

该角色允许您(或Qt)选择应返回哪种数据表示。

另一个潜在用途是存储有关在视图中渲染数据时使用的工具提示,背景或前景色的信息。

基本上,您的视图将使用角色来获取模型中特定条目所需的信息。如果您有任何数据库经验,则可以将角色视为与数据库中的列类似,其中数据库中的行对应于数据片段。