4

I want to use qml with master-detail interface, but i don't know how to pass current item to detail view right way. The ListView in master view uses C++ model (add-on of QSQLTableModel, it's work fine) and I see two ways to pass item:

  1. Create C++ classes with fields with static name like QSqlRecord field names and pass it to qml with w->rootContext()->setContextProperty() (w is QDeclarativeView *), but now i don't use any classes like this and can change my database and qml views without changing c++ code, I would like to save it

  2. Create a lot of properties in any detail qml like

    Rectangle {
      id: mainRect
      property alias myFieldName: txt_nominal.text
      Column {
    
        width: parent.width
        Text {
            id: txt_nominal
            font.bold: true
        }
      }
    }
    

and set this properties from c++ code by setting w->rootContext()->setContextProperty(record.fieldName(i),record.field(i).value()); (record - QSqlRecort at current row)

Is there any easier way to solve my problem?

PS The code I wrote above is not checked for accuracy, and is written to make it more clear what I mean

UPD

Maybe it will be useful for somebody, I discovered 3-rd way, rather, the modification of second - you can wrap fields into QVariantMap and pass only one object to qml. This is exactly what I wanted

in cpp:

QVariantMap testObject;
testObject["testField"]="first string from cpp";
testObject["testField2"]="second string from cpp";
rootContext()->setContextProperty("testObject",testObject);

in qml:

Text {
        id: simpleTextt
        text: testObject.testField
        anchors.centerIn: parent
    }
4

1 回答 1

3

您可以使用委托的isCurrentItem属性将数据从 ListView 委托传递到您的详细信息 qml。这样,您无需添加额外的 c++ 代码就可以逃脱。这基本上是您的第二种方法,但没有 c++。只要您要更改的每个 QML 元素都有一个id ,您也不需要添加许多属性。

如果您有许多不同的 QML 用于不同的详细信息视图,您还必须使用 Loader 来加载适当的详细信息 QML。

只是一个玩具示例,假设您对于列表中的所有元素只有一个详细信息模板(如上所述,如果不是这种情况,您可以使用 loader 而不是detailsRect):

Rectangle {
  width: 300; height: 400

  Rectangle {
    id: detailsRect
    anchors.right: parent.right
    width: 100
    height: 500
    color: "blue"
    Text {
      id: detailsText
      text: ""
    }
  }

ListView {
  id: list
  anchors.fill: parent
  model: 20

  delegate: Rectangle {
    color: ListView.isCurrentItem ? "red" : "green"
    width: 40
    height: 40

    Text {
        text: index
    }

    ListView.onIsCurrentItemChanged: {
        if(ListView.isCurrentItem)
        {
            detailsRect.color = "yellow"
            detailsText.text = index
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            list.currentIndex = index
        }
    }
  }
}
}
于 2012-11-30T13:06:12.450 回答