来自委托的QML TableView访问模型属性

时间:2014-04-04 23:00:02

标签: qt qml qt-quick qtquick2 qtquickcontrols

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

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

有什么想法吗?谢谢!

3 个答案:

答案 0 :(得分:15)

缺少一些文档。在项目委托中,您可以访问以下内容(取自the source code of TreeView.qml):

  • styleDatasee documentation
  • model(目前未记录)
  • modelData(目前没有记录,不确定这一点,但我想它与ListView类似)

(顺便说一下,文档中也缺少什么,但有用的是styleData.role。此外,其他代表的文档也缺少一些可用的属性;最好是查看源代码QML文件的代码,并查看实例化您的委托的Loader元素。作为一个加号,您将了解令人毛骨悚然的东西如何工作。;))

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

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

如果您正在使用C ++ QAbstractItemModel或朋友,最好是在模型类中添加一个插槽,该插槽仅包含行和角色名称,因为这是TableView使用的信息(也不是角色)数字也不是列......)。

然而在这两种情况下都不应该在属性绑定中使用表达式!由于您不使用属性系统来访问数据,因此通知系统将无法工作。根据你的问题,我猜你想在带有绑定的表达式中使用它。我不知道如何正确地手动收听模型中的更改。

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

  • 在一个项目中,您可以通过将对象树向上移动两次来访问同一行的其他项目(首先是实例化组件的Loader,然后是实际的行)然后向下两次(第一次到特定的子对象,它是一个Loader,然后是它的实例化项目)。您需要知道要访问的列号(而不是角色名称),我假设您要访问第一列(索引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"
}

答案 1 :(得分:3)

我认为如果您阅读TableViewItemDelegateLoader.qml的源代码(它是ThreadLocal<T>中的私有代码),这很容易
要访问您使用的任何角色,请使用:qtquickcontrol

对于exp:model[your_role_name]

答案 2 :(得分:1)

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

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

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

  • 创建某个项目时(您想要更改文字样式的位置) 另一个元素(从中接收身份)还不能 创建
  • 您可能没有&#34; parent&#34;项目创建(即绑定将 被打破)

就我而言,深度自定义的最佳解决方案是为ListView创建简单的包装器。在这种情况下,您可以访问委托中的完整行数据而无需开销。制作组件的重点(&#34;我自己的ListView作为表&#34;):

  • 创建独立标题(RectangleItem) - 请勿使用标题表单ListView。这样可以修复任意数量的数据。
  • ListView换行至ScrollView(如果您需要滚动条)
  • 在列表中使用Clip: true属性以使其正确
  • 设置highlight的样式并在ListView
  • 中设置highlightFollowsCurrentItem:true

作为将来的奖励,这可以用于制作&#34; TreeTable&#34; :)