4
votes

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
    }
1
Does your c++ model already have all the fields that will be displayed in details view or do you have to do some additional data fetching for the details view?JuliusG
Model alredy have all fields and I know which fields have current model (program have some tables hierarchy, any table has his own qml view, transition between this view described into c++ code).aknew

1 Answers

3
votes

You could use the isCurrentItem property of the delegate to pass the data from ListView delegate to your details qml. That way you could get away without have to add additional c++ code. This is basically your second approach but without c++. You also do not need to add many properties as long as each of your QML elements that you want to change have an id.

If you have a number of different QML for different details views you would also have to use the Loader to load the appropriate details QML.

Just a toy example assuming that you have only one details template for all of your elements in the list (as mentioned above if that is not the case than you can use loader instead of 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
        }
    }
  }
}
}