QML/C++ Master/Detail ComboBox/Listview
-
On Qt 5.7, Quick Controls 2.0, I have a master ComboBox with a slave ListView. How can the slave change when the user changes the ComboBox selection?
For exemple:
Imagine that I have a list of persons, and every person has a list of cars:
- Person1 - car1, car2, car3
- Person2 - car4
- Person3 - car5, car6, car7, car8
- Person4 - car9, car10
...
The persons must appears on ComboBox and when the users selects a person, the Listview must show person's cars.
I've tried this, but the carsRole is never called on data member, so the ListView doesn't show anything.
QML:
ComboBox { textRole: "name" model: personsModel } ListView { model: personsModel.cars }
C++
enum PersonsRoles { nameRole = Qt::UserRole + 1, carsRole }; QVariant PersonsModel::data(const QModelIndex &index, int role) const { int row = index.row(); if ((row < 0) || (row >= _persons.size())) { return QVariant(); } switch (role) { case nameRole: return _persons.at(row); case carsRole: { return QVariant::fromValue(new CarsModel(row)); } } return QVariant(); } QHash<int, QByteArray> PersonsModel::roleNames() const { QHash<int, QByteArray> roles; roles[nameRole] = "name"; roles[carsRole] = "cars"; return roles; }
-
On Qt 5.7, Quick Controls 2.0, I have a master ComboBox with a slave ListView. How can the slave change when the user changes the ComboBox selection?
For exemple:
Imagine that I have a list of persons, and every person has a list of cars:
- Person1 - car1, car2, car3
- Person2 - car4
- Person3 - car5, car6, car7, car8
- Person4 - car9, car10
...
The persons must appears on ComboBox and when the users selects a person, the Listview must show person's cars.
I've tried this, but the carsRole is never called on data member, so the ListView doesn't show anything.
QML:
ComboBox { textRole: "name" model: personsModel } ListView { model: personsModel.cars }
C++
enum PersonsRoles { nameRole = Qt::UserRole + 1, carsRole }; QVariant PersonsModel::data(const QModelIndex &index, int role) const { int row = index.row(); if ((row < 0) || (row >= _persons.size())) { return QVariant(); } switch (role) { case nameRole: return _persons.at(row); case carsRole: { return QVariant::fromValue(new CarsModel(row)); } } return QVariant(); } QHash<int, QByteArray> PersonsModel::roleNames() const { QHash<int, QByteArray> roles; roles[nameRole] = "name"; roles[carsRole] = "cars"; return roles; }
@lqsa One way is to use QStringList for Listview model and add Q_invokable method in model to return cars for current index:
Q_INVOKABLE QStringList personCars(int index)const{ // check index is valid _persons.at(index)->cars(); }
Then in catch currentIndexChanged in combobox:
ComboBox { textRole: "name" model: personsModel onCurrentIndexChanged: list.model = personsModel.personCars() } ListView { id: list }
-
Thank you,
Finally I've done this solution: ```
http://www.qtcentre.org/threads/66408-QML-C-Master-Detail-ComboBox-Listview