ListModel needs data from other model
-
Hi all -
I have a screen with a GridView that displays summaries of equipment items. When one of the items is clicked, I open a detail drawer. The drawer needs information about the selected (clicked) item.
// EquipmentScreen.qml GridView { model: equipmentModel // from C++ EquipmentCard { id: card name: model.name imageURI: "qrc:/icons/VariableSpeed.svg" uuid: model.uuid onCardClicked: { drawer.open() drawerStack.push("EquipmentDetail.qml") } // EquipmentDetail.qml RowLayout { ListModel { id: clickables ListElement { name: "Name should go here"; image: "" } // what to do here? ListElement { name: "Diagnostics"; image: "" } ListElement { name: "Operations"; image: "" } ListElement { name: "Settings"; image: "" } ListElement { name: "Zones"; image: "" } } ListView { model: clickables delegate: Rectangle { Text { text: model.name }
Can I somehow "inject" this drawer with information from the GridView item? And if not, how do I derive this information from within the drawer?
Thanks...
-
@JoeCFD in my EquipmentModel class, I have this:
Q_INVOKABLE EquipmentItem getItem(int index) { return m_list->getItem(index); }
And my EquipmentItem class has this:
Q_PROPERTY(QString name MEMBER m_name)
So I think I have my C++ covered. And I can get the name in QML using:
property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name;
So, now how do I use that in my model? I tried this:
ListModel { id: clickables property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name; ListElement { name: equipmentItem; color: "blue" }
But I get this error:
ListElement: cannot use script for property value
Thanks...
@mzimmers said in ListModel needs data from other model:
ListElement: cannot use script for property value
something like this?
Component.onCompleted: { /*<==== can be a slot */ clickables.get(0).name = equipmentModel.getItem(equipmentModel.index().name()); or clickables.get( index ).name = equipmentModel.getItem(equipmentModel.index().name()); }
-
Populating the temporary ListModel when a cell from the GridView is clicked is a waste of memory and compute time.
- Put all of the data in
equipmentModel
. - Remove the
clickables
ListModel, and useequipmentModel
for both the ListView as well as the GridView. - Bind the ListView's currentIndex to the GridView's current index.
- Size the ListView delegate to fit the view, and disable flicking.
- Put all of the data in
-
Populating the temporary ListModel when a cell from the GridView is clicked is a waste of memory and compute time.
- Put all of the data in
equipmentModel
. - Remove the
clickables
ListModel, and useequipmentModel
for both the ListView as well as the GridView. - Bind the ListView's currentIndex to the GridView's current index.
- Size the ListView delegate to fit the view, and disable flicking.
@jeremy_k the clickables model is something I put together to use for creating a series of buttons in the left column of EquipmentDetail, so I don't think I can get rid of it completely.
I like your idea of using the original equipmentModel, though I'm not sure how to access information about an individual item (just one item) from the model, which uses a list as its basis. Is it going to look something like (pseudocode here):
equipmentModel.getItem(equipmentModel.index).name()
I know this isn't right, but am I on the right track?
Thanks...
- Put all of the data in
-
@jeremy_k the clickables model is something I put together to use for creating a series of buttons in the left column of EquipmentDetail, so I don't think I can get rid of it completely.
I like your idea of using the original equipmentModel, though I'm not sure how to access information about an individual item (just one item) from the model, which uses a list as its basis. Is it going to look something like (pseudocode here):
equipmentModel.getItem(equipmentModel.index).name()
I know this isn't right, but am I on the right track?
Thanks...
@mzimmers said in ListModel needs data from other model:
@jeremy_k the clickables model is something I put together to use for creating a series of buttons in the left column of EquipmentDetail, so I don't think I can get rid of it completely.
Unless the model is an ObjectModel, it should not contain buttons or visual items of any sort. It may contain the data used to populate a view with buttons, but where does that data come from? If the answer is some mutation of data from the other model, take the data from the model and mutate in the view delegate.
I like your idea of using the original equipmentModel, though I'm not sure how to access information about an individual item (just one item) from the model,
Access works the same as with any other view.
GridView { id: gv model: equipmentModel delegate: Text { text: model.name } } ListView { interactive: false model: equipmentModel currentIndex: gv.currentIndex delegate: Text { width: ListView.view.width height: ListView.view.height text: "The current item is " + model.name Button { text: model.buttonName; onClicked: Qt.quit() } } }
equipmentModel.getItem(equipmentModel.index).name()
Is
name
accessible as a role inequipmentModel
? If it is displayed in the context of something that acts like a view, it should be. -
@mzimmers said in ListModel needs data from other model:
@jeremy_k the clickables model is something I put together to use for creating a series of buttons in the left column of EquipmentDetail, so I don't think I can get rid of it completely.
Unless the model is an ObjectModel, it should not contain buttons or visual items of any sort. It may contain the data used to populate a view with buttons, but where does that data come from? If the answer is some mutation of data from the other model, take the data from the model and mutate in the view delegate.
I like your idea of using the original equipmentModel, though I'm not sure how to access information about an individual item (just one item) from the model,
Access works the same as with any other view.
GridView { id: gv model: equipmentModel delegate: Text { text: model.name } } ListView { interactive: false model: equipmentModel currentIndex: gv.currentIndex delegate: Text { width: ListView.view.width height: ListView.view.height text: "The current item is " + model.name Button { text: model.buttonName; onClicked: Qt.quit() } } }
equipmentModel.getItem(equipmentModel.index).name()
Is
name
accessible as a role inequipmentModel
? If it is displayed in the context of something that acts like a view, it should be.@jeremy_k the model doesn't contain buttons; just the text for the buttons. (This might be overkill, but the problem remains.)
The first button is kind of a special case in that it should contain information about the individual item in the model. Eventually I'll need other information from the model as well.
So here's what I tried:
ListModel { id: clickables ListElement { name: equipmentModel.getItem(equipmentModel.index().name()); color: "blue" } ListElement { name: "Diagnostics"; color: "green" } ListElement { name: "Operations"; color: "purple" } ListElement { name: "Settings"; color: "yellow" } ListElement { name: "Zones"; color: "black" } }
At runtime I get an error:
qrc:/qt/qml/nga_demo/EquipmentDetail.qml:27 ListElement: cannot use script for property value
-
@jeremy_k the model doesn't contain buttons; just the text for the buttons. (This might be overkill, but the problem remains.)
The first button is kind of a special case in that it should contain information about the individual item in the model. Eventually I'll need other information from the model as well.
So here's what I tried:
ListModel { id: clickables ListElement { name: equipmentModel.getItem(equipmentModel.index().name()); color: "blue" } ListElement { name: "Diagnostics"; color: "green" } ListElement { name: "Operations"; color: "purple" } ListElement { name: "Settings"; color: "yellow" } ListElement { name: "Zones"; color: "black" } }
At runtime I get an error:
qrc:/qt/qml/nga_demo/EquipmentDetail.qml:27 ListElement: cannot use script for property value
-
@mzimmers I guess you may need something like:
equipmentModel.getIndexItem( index )
and
equipmentModel.getItem(equipmentModel.index().name())
is better done inside equipmentModel
@JoeCFD in my EquipmentModel class, I have this:
Q_INVOKABLE EquipmentItem getItem(int index) { return m_list->getItem(index); }
And my EquipmentItem class has this:
Q_PROPERTY(QString name MEMBER m_name)
So I think I have my C++ covered. And I can get the name in QML using:
property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name;
So, now how do I use that in my model? I tried this:
ListModel { id: clickables property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name; ListElement { name: equipmentItem; color: "blue" }
But I get this error:
ListElement: cannot use script for property value
Thanks...
-
@JoeCFD in my EquipmentModel class, I have this:
Q_INVOKABLE EquipmentItem getItem(int index) { return m_list->getItem(index); }
And my EquipmentItem class has this:
Q_PROPERTY(QString name MEMBER m_name)
So I think I have my C++ covered. And I can get the name in QML using:
property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name;
So, now how do I use that in my model? I tried this:
ListModel { id: clickables property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name; ListElement { name: equipmentItem; color: "blue" }
But I get this error:
ListElement: cannot use script for property value
Thanks...
@mzimmers said in ListModel needs data from other model:
ListElement: cannot use script for property value
something like this?
Component.onCompleted: { /*<==== can be a slot */ clickables.get(0).name = equipmentModel.getItem(equipmentModel.index().name()); or clickables.get( index ).name = equipmentModel.getItem(equipmentModel.index().name()); }
-
@mzimmers said in ListModel needs data from other model:
ListElement: cannot use script for property value
something like this?
Component.onCompleted: { /*<==== can be a slot */ clickables.get(0).name = equipmentModel.getItem(equipmentModel.index().name()); or clickables.get( index ).name = equipmentModel.getItem(equipmentModel.index().name()); }
@JoeCFD that works! I introduced an intermediate variable for clarity:
ColumnLayout { property string equipmentItem: equipmentModel.getItem(equipmentModel.index).name; Component.onCompleted: clickables.get(0).name = equipmentItem ListModel { id: clickables Component.onCompleted: console.log("equipmentItem is " + equipmentItem) ListElement { name: "TO BE FILLED IN AT RUNTIME"; color: "blue" } ...
This is functional, though I get the impression from @jeremy_k's comments that it might not be the desired way to go about this.
-
M mzimmers has marked this topic as solved on