qt - QML:如何将模型属性传递给加载在 GridView(或 ListView)委托(delegate)中的委托(delegate)?

标签 qt listview gridview model qml

我正在尝试构建一个内部托管 GridView 的可重用 QML 组件。 GridView 中的每个元素都有一组在整个应用程序中通用的行为(主要是显示和基于鼠标的东西)。但是,GridView 元素中显示的内容会根据用例而变化。 (也就是说,一个 GridView 使用相同的封装组件,但在应用程序的其他地方它可能使用不同的组件。)

所以,我想做的是让每个调用都提供一个委托(delegate),该委托(delegate)添加到 GridView 中的每个元素,这已经是一个委托(delegate)。换句话说,是这样的:

MyGrid.qml

import QtQuick 1.1

Rectangle {
  id: myGrid
  objectName: "myGrid"

  property Component internalDelegate
  property variant internalModel

  GridView {
    anchors.fill: parent

    delegate: Row {
      Loader {
        sourceComponent: myGrid.internalDelegate
      }
    }

    model: parent.internalModel
  }
}

这个想法是 GridView 委托(delegate)中的 Loader 加载用户提供的委托(delegate),它看起来像这样:

Main.qml
import QtQuick 1.1

Rectangle {
  anchors.fill: parent

  width: 300
  height: 200

  MyGrid {
    anchors.fill: parent

    internalDelegate: Text {
      text: name
    }

    internalModel: ListModel {
      ListElement {
        name: "a"
      }

      ListElement {
        name: "b"
      }
    }
  }
}

但是,这不起作用。 QML 报告“名称”是文本元素内的未知变量。如果我用字符串(即“hello”)替换 name 变量,它会按预期工作。

我的问题是,如何将“名称”变量传递给 internalDelegate,或者更好的是,使整个模型可用,以便 internalDelegate 可以访问所有它们(因为调用者也在定义模型)。

一个附带的问题是:有没有更好的方法来做到这一点?

最佳答案

我正在回答我自己的问题,因为我一直在解决这个问题并找到了一个可以接受的解决方案。我没有将此问题标记为已回答(尚未),因为我想知道是否有更简单或更有效的解决方案。

以下是我解决此问题的方法:我将 Binding 组件与 Loader 一起使用,并创建了一个自定义 MyDelegate 组件,该组件具有模型当前 ListElement 的变体属性。这是修改后的代码,其中包含注释标记的重要更改。

Main.qml

import QtQuick 1.1

Rectangle {
  anchors.fill: parent

  width: 300
  height: 200

  MyGrid {
    anchors.fill: parent

    // *** Use MyDelegate rather than generic Component and refer to
    // *** model's properties via MyDelegate's model property
    internalDelegate: MyDelegate {
      Text {
        text: model.index + model.name
      }
    }

    internalModel: ListModel {
      ListElement {
        name: "a"
      }

      ListElement {
        name: "b"
      }
    }
  }
}

MyGrid.qml
import QtQuick 1.1

Rectangle {
  id: myGrid
  objectName: "myGrid"

  property Component internalDelegate
  property variant internalModel

  GridView {
    anchors.fill: parent

    delegate: Row {
      Loader {
        id: loader

        sourceComponent: myGrid.internalDelegate

        // *** Bind current model element to the component
        // *** when it's loaded
        Binding {
          target: loader.item
          property: "model"
          value: model
          when: loader.status == Loader.Ready
        }
      }
    }

    model: parent.internalModel
  }
}

关键的添加是一个自定义的 MyDelegate 组件,它将模型属性定义为一个变体。这在解释时绑定(bind),这意味着在引用模型的 name 属性时 Main.qml 中没有错误。

MyDelegate.qml
import QtQuick 1.1

Rectangle {
  property variant model
}

有些东西告诉我有一种更简单的方法可以做到这一点,但现在可行。

关于qt - QML:如何将模型属性传递给加载在 GridView(或 ListView)委托(delegate)中的委托(delegate)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8450992/

相关文章:

c++ - 私有(private)QT信号

android - 如何在 ListView 项中显示 map View 位置?

listview - 在 JavaFx 8 中创建具有自定义背景颜色的 CheckBoxListCell

flutter - 如何在 Flutter 中创建 GridView 布局

javascript - 使用jquery计算gridview中的行总计和总计

c# - GridView 中的超链接列

c++ - 找出在 QTableWidget 中选择了哪一列

c++ - qt c++ qpainter 与 QVector

android - Android ListView 的无限适配器

c++ - QGraphicsView 和背景中的复杂多边形