【问题标题】:What is "role" and where it comes from? (How to change background color after editing QTableView cell?)什么是“角色”,它来自哪里? (编辑 QTableView 单元格后如何更改背景颜色?)
【发布时间】:2013-12-16 09:41:46
【问题描述】:

我试图在编辑后更改 qtable 单元格的背景颜色。我已经看过问题“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 个“声誉点”,抱歉。

【问题讨论】:

  • 关于你的最后一点:无需道歉 - 提出一个新问题是正确的做法。

标签: python pyqt qtableview


【解决方案1】:

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

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

编辑(一点程序解释):

好吧,显然您创建了一个实现 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 的正确动词;))并作为单个整数返回。

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

这种方法让我们将数据控制器和数据查看器分开。 Model 不知道使用它的视图如何显示数据(可能不止一个,它们会一直同步)。它被称为MVC - 模型/视图/控制器。不幸的是,Qt 对其 MVC 实现的命名具有误导性,但您可以阅读更多信息,例如here.

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

【讨论】:

  • 感谢链接,但你能解释一下在上面的程序中每一步发生了什么吗?那太好了
  • 好的,我编辑了我的回复。希望它现在更有帮助。
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2012-12-05
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    • 2015-06-27
    • 2011-09-24
    • 2013-04-12
    • 2021-10-31
    • 1970-01-01
    相关资源
    最近更新 更多