首页 文章

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

提问于
浏览
6

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

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

有任何想法吗?谢谢!

3 回答

  • 3

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

    • styleDatasee documentation

    • model (目前未记录)

    • modelData (目前没有记录,不确定这个,但我想它与 ListView 类似)

    (顺便说一句,文档中也缺少什么,但有用的是styleData.role . 另外,其他委托的文档也缺少一些可用的属性;最好是查看QML文件的源代码并拥有一个寻找实例化你的委托的Loader元素 . 作为一个优点,你可以了解这些令人毛骨悚然的东西是如何运作的 . ;))

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

    如果你're using QML' s ListModel ,那么你可以使用model.getmodel.get(styleData.row)[styleData.role] 然后应该工作(因为我很少使用,所以请不要测试,请提供反馈) .

    如果're using a C++ QAbstractItemModel or friends, the best is to add a slot to the model class which takes just the row and role name, since that'是 TableView 使用的信息(也不是角色编号,也不是列......) .

    However 在这两种情况下你都不应该使用属性系统来访问数据 . 根据你的问题,我猜你想在带有绑定的表达式中使用它 . 我不知道如何正确地手动收听模型中的更改 .

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

    • 在一个项目中,您可以通过将对象树向上移动两次来访问同一行的其他项目(首先是实例化组件的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

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

    对于exp: model["comment"]

  • 13

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

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

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

    • 当创建某个项目(您想要更改文本样式的位置)时,尚无法创建另一个元素(从中接收标识)

    • 项目创建时可能没有"parent"(即绑定将被破坏)

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

    • 创建独立 Headers ( RectangleItem ) - 不要使用 Headers 形式 ListView . 这使得它可以修复任何数量的数据 .

    • 包裹 ListViewScrollView(如果您需要滚动条)

    • 在列表中使用Clip: true属性以使其正确

    • 设置highlight的样式并在 ListView 中设置highlightFollowsCurrentItem:true

    作为未来的奖金,这可能用于制作“TreeTable”:)

相关问题