3
votes

Currently some students and I are programming a little application with QtQuick.
We have the following TableView:

TableView {
    model: ListModel {
        id: orderListModel
        Component.onCompleted: {
            var tOrderList = orderController.getOrderList();
            for(var i = 0; i < tTicketList.length; ++i){
                orderListModel.append(tOrderList[i]);
            }
        }
    }


    TableViewColumn {
        role: "orderId"
        title: "Auftragsnummer"
        width: 100
    }
    TableViewColumn {
        role: "customer.name"
        title: "Kunde"
        width: 100
    }
}

getOrderList returns a QList<Object*> with all the orders. The Order class has a property customer

Q_PROPERTY(Customer* customer READ getCustomer NOTIFY customerChanged)

which in turns has a property called name.

We would like to show the latter property inside the TableView but unfortunately only the orderId property of Order does works.

What value should have the second role? How can we access data of the nested object?

1

1 Answers

2
votes

According to the documentation you can use QList<QObject*> as a model for a view directly, without manually copying the data as you did. In particular:

The QObject* is available as the modelData property. As a convenience, the properties of the object are also made available directly in the delegate's context.

Considering the example linked in the documentation we have that a property of the QObject can be used as role in the following way:

ListView {
    width: 100; height: 100

    model: myModel                     // injected QList<QObject*> context property
    delegate: Rectangle {
        height: 25
        width: 100
        color: model.modelData.color   // without "modelData" it would not work
        Text { text: name }
    }
}

The same applies for nested properties. If our QObject-derived object has a QObject property, like in your case, we can retrieve it via modelData and then access it's properties. So, for instance with the customer property, we would have something like this in the delegate:

Text { text: model.modelData.customer.name }

That's true for ListView et similia whereas I'm not sure it could be done directly with TableView. One possible workaround would be to combine the usage of the QObject-derived role with styleData.value. You can define the usage of the role in the role property and access the inner property inside the styleData.value. A solution for your case would look like the following (assuming myModel is a context property as the example above):

TableView  {
    width: 100; height: 100

    model: myModel

    TableViewColumn {
        role: "customer"
        title: "Kunde"
        width: 100

        delegate: Text {
            text: styleData.value.name  // accessing the property
        }
    }

    itemDelegate: Item {   }            // should be set to empty to avoid warnings
}

A downside of this approach is that you should implement a delegate for each column.