8

我有一个 TableView,我已经为它定义了自己的 itemDelegate。现在,在这个委托中,我可以使用 styleData.value 访问列的值,但我还需要访问同一项目中的其他属性,但我找不到如何访问。

我需要这个,因为文本样式需要根据项目模型的其他一些属性进行更改。

有任何想法吗?谢谢!

4

3 回答 3

16

缺少一些文档。在项目委托中,您可以访问以下内容(取自的源代码TreeView.qml):

  • styleData见文档
  • model(目前没有记录)
  • modelData(目前没有记录,不确定这一点,但我猜它类似于ListView

(顺便说一下,文档中也缺少但有用的styleData.role是实例化您的委托的加载器元素。此外,您还可以了解这些令人毛骨悚然的东西是如何工作的。;))

使用model和 行/列信息,您可以导航到项目数据。此代码取决于模型的类型。

如果您使用的是 QML ListModel,那么您可以使用model.get:model.get(styleData.row)[styleData.role]应该可以工作(未经测试,因为我很少使用它,请提供反馈)。

如果您使用的是 C++ QAbstractItemModel 或朋友,最好在模型类中添加一个槽,该槽仅采用行和角色名称,因为这是使用的信息TableView(既不带有角色编号也不带有列......) .

但是,在这两种情况下,您都不应该在属性绑定中使用表达式!通知系统将不起作用,因为您不使用属性系统来访问数据。根据您的问题,我猜您想在具有绑定的表达式中使用它。我不知道如何手动正确收听模型中的更改。

另一种方法是访问该行的其他项目并在那里提供一个属性。一些提示:

  • 从一个项目中,您可以通过将对象树向上移动两次(首先到实例化您的组件的加载器,然后到实际行)然后向下两次(首先到特定的子对象,即加载器,然后是它的实例化项)。您需要知道要访问的列号(不是角色名称),我假设您要访问第一列(索引 0):

    parent.parent.children[0].item
    
  • 您可以使用每个项目中的属性来提供模型数据。假设一个简单的 Text 元素,这可能是:

    Text {
        property variant value: styleData.value // <-- Here you make it available
    
        // your other stuff
    }
    

将它们放在一起可能如下所示。在这个例子中,我假设第一行包含一个整数,如果它为零,第二列应该是红色的。

// (within TableView)
itemDelegate: Text {
    property variant value: styleData.value
    text: styleData.value
    color: (styleData.column == 1 && parent.parent.children[0].item.value === 0)
            "red" : "black"
}
于 2014-04-07T22:49:42.917 回答
5

我认为如果您阅读 TableViewItemDelegateLoader.qml 的源代码(它是 中的私有代码qtquickcontrol) 很容易
访问您使用的任何角色,请使用:model[your_role_name]

对于经验:model["comment"]

于 2015-10-19T08:15:57.593 回答
3

今天面临同样的问题,这是我调查的结果(Qt 5.2.x)

如果您对 TableView 有硬性限制,那么只有一个正确的解决方案 -model.get(styleData.row)["roleForStyling"]像 @leemes 所写的那样使用。但是,如果您在模型中有大量数据并使用例如代理模型进行排序/过滤,它会非常慢。

@leemes 答案的直接解决方案很棒,但在一般情况下不起作用,因为在TableView任何Item包装中Loader,因此独立于父项和其他项:

  • 创建某个项目时(您要更改文本样式的位置)另一个元素(从中接收身份)还不能创建
  • 您在创建项目时可能没有“父级”(即绑定将被破坏)

就我而言,深度定制的最佳解决方案是为ListView. 在这种情况下,您可以在没有开销的情况下访问委托中的完整行数据。制作组件的亮点(“我自己的ListView as table”):

作为将来的奖励,这可用于制作“TreeTable”:)

于 2014-11-24T10:52:24.680 回答