If this is your first visit, be sure to
check out the
FAQ
by clicking the
link above. You may have to
register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.
Welcome to
Qt Centre
.
Qt Centre
is a community site devoted to programming in C++ using the
Qt framework
. Over 90 percent of questions asked here gets answered. If you are looking for information about Qt related issue —
register
and post your question.
You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our
free
community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please,
join our community today
!
If you have any problems with the registration process or your account login, please
contact us
.
Can you give an example of what you intend to do?
A ListView works on a single model and single delegate at any given time, but of course either can be changed during runtime, etc.
Cheers,
Thanks for the reply.
My requirement is like i am getting different models from C++ side at runtime. Similarly i have to show these data in different kind of delegates in same qml.
Basically its a list screen which has different categories.
I tried to use loader for different delegates but i am not able to access the model from loader , however if i explicitly use one , one data from model as like variables i am able to do it , but model as a whole not able to.
I have even read that loader should be avoided .
Can you please suggest what kind of a design should i prefer for this
There are several options:
- you get the model data into local properties of the main delegate and then give the main delegate object to the loaded ite
- use Binding elements to bind the model data to the loaded item's properties
- make the ListView's delegate property an expression that evaluates to the wanted delegate instead of using a Loader
1.Yes active model is getting replaced by another model.Yes we are binding it to a c++ property.
2.Delegate changes for different model , different delegates are used.Some delegates, has to show only one information in field in list , some two , some more.
3.I tried the 3rd one , but whenever i am assigning from one delegate to another , it first goes and executes the first delegate and then the other one , hence i am getting reference errors, there is some context problem i think.I did not understand the first and 2nd option how to do it. If possible , please can you give a small code snippet for those 2 options.
4. I will search and let you know where i read , loader is not a good option.
5.I hope i can make you understand .
Thanks a lot for ur reply
So there is no direct association between model and delegate?
You need to switch delegate even if the model stays the same?
Base on some data in the model?
In the first option you have some property in the item that gets loaded that is set to one of the object that always exist, e.g. the main delegate.
The loaded item always accesses that object's properties.
For the second option just look at the documentation of the Binding element:
http://doc.qt.io/qt-5/qml-qtqml-binding.html
The target would be the Loader's "item", the property whatever it has and the value would be the "model" expression.
It is quite difficult to answer questions on such a highly abstract level, so any example would help.
Cheers,
Thank you very much for the reply.
So there is no direct association between model and delegate?
You need to switch delegate even if the model stays the same?
Base on some data in the model?
Yes there is direct association between model and delegate , for a specific model we have to show the details in a specific format.
So i have taken a specific delegate, for one model one delegate.Since we are getting the model from C++ and i see that this model contains data which is
not present in another models , so i have to make different delegates for different model , since my requirement is like that.
Can you give an example of how the binding for the delegate property looked in such a case?
Since my model is changing suppose the user has chosen some new categaory on a button press
Hence i am doing like
OnClicked{
mylistview.model=newmodel//the new model for the category
mylistview.delegate =newdelegate//the new way i have to show the data with new fields
Here in the above case i see when i assign like this it once again goes and executes the mylistview.delegate and then it goes to execute the newdelegate , hence in the previous case "mylistview.delegate" is executed and since the model is changed to the new model hence i get reference error.
In the first option you have some property in the item that gets loaded that is set to one of the object that always exist, e.g. the main delegate.
The loaded item always accesses that object's properties.
This wont be useful in my case as i have dynamic model
For the second option just look at the documentation of the Binding element:
http://doc.qt.io/qt-5/qml-qtqml-binding.html
The target would be the Loader's "item", the property whatever it has and the value would be the "model" expression.
I already tried the above like below
Loader
........
property variant mymodel = model from C++
onLoaded:
Binding {
target: myloader.item
property: "mymodel "
value: mymodel
when: loader.status == Loader.Ready
but i see that the delegate is not able to access the data in this case.
however if i do something like this
inside loader
property var myalbumname = albumname //this is one role inside model
In the above case i am able to access the data in delegate but if iam trying to expose model as whole in loader i am not , i am not able to figure out where i am going wrong.
So there is a property that returns the current model.
Either on the same object or on each model have a property that returns some kind of identifier.
Then in QML, you use that identifier to switch between Components for the delegate
Qt Code:
Switch view
ListView {
model: cppObject.currentModel
delegate: switch (cppObject.currentDelegate) {
case "album": return albumDelegate;
//....
}
}
Component {
id: albumDelegate
Text {
text: model.albumname
}
}
ListView {
model: cppObject.currentModel
delegate: switch (cppObject.currentDelegate) {
case "album": return albumDelegate;
//....
Component {
id: albumDelegate
Text {
text: model.albumname
To copy to clipboard, switch view to plain text mode
mylistview.model=newmodel//the new model for the category
mylistview.delegate =newdelegate//the new way i have to show the data with new fields
Here in the above case i see when i assign like this it once again goes and executes the mylistview.delegate and then it goes to execute the newdelegate , hence in the previous case "mylistview.delegate" is executed and since the model is changed to the new model hence i get reference error.
I see.
Maybe first set the delegate to undefined, then change the model, then set the delegate to the new one
but i see that the delegate is not able to access the data in this case.
however if i do something like this
inside loader
property var myalbumname = albumname //this is one role inside model
In the above case i am able to access the data in delegate but if iam trying to expose model as whole in loader i am not , i am not able to figure out where i am going wrong.
You don't want to access the model inside the delegate, but as usual the current index in the model, i.e. the data at for the current item.
But that doesn't help you anyway since your delegates all need different data.
Cheers,
Thanks for the reply.
I understand from your reply that now i have to switch between the components , but as i will be assigning from one previous to the new delegate , again i will get a reference error , just to verify what you suggested i have written a small example which contains 2 models and 2 delegates and i try to assign it alternatively , but as i am doing the first assignment of model and delegate in the first mouse click i get refernce error as usual
qml: entering assigning model
qrc:/main.qml:57: ReferenceError: name is not defined
qrc:/main.qml:57: ReferenceError: name is not defined
qrc:/main.qml:57: ReferenceError: name is not defined
qrc:/main.qml:64: ReferenceError: mylistview is not defined
qml: entering assigning modeln
Also below i am posting the code i wrote , please can you suggest how to get out of these errors.
Qt Code:
Switch view
//////////////////////////////////////////////////////
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
visible: true
MouseArea {
anchors.fill: parent
onClicked: {
console.log("entering assigning model")
mylistview.model=model2
mylistview.delegate=comp2
}
}
ListModel{
id:model1
ListElement{
name:"Element1"
}
ListElement{
name:"Element2"
}
ListElement{
name:"Element3"
}
}
ListModel{
id:model2
ListElement{
fame:"Element4"
}
ListElement{
fame:"Element5"
}
ListElement{
fame:"Element6"
}
}
Component
{
id:comp1
Row{
Rectangle
{
width:50
height:50
color:"red"
border.width: 2
border.color: "black"
Text {
text: name
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log("entering assigning model")
mylistview.model=model2
mylistview.delegate=comp2
}
}
}
}
}
Component
{
id:comp2
Row{
Rectangle
{
width:50
height:50
color:"blue"
border.width: 2
border.color: "black"
Text {
text: fame
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log("entering assigning model")
mylistview.delegate=comp1
mylistview.model=model1
}
}
}
}
}
ListView
{
id:mylistview
anchors.fill: parent
model:model1
delegate: comp1
}
}
////////////////////////////////////
//////////////////////////////////////////////////////
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
visible: true
MouseArea {
anchors.fill: parent
onClicked: {
console.log("entering assigning model")
mylistview.model=model2
mylistview.delegate=comp2
ListModel{
id:model1
ListElement{
name:"Element1"
ListElement{
name:"Element2"
ListElement{
name:"Element3"
ListModel{
id:model2
ListElement{
fame:"Element4"
ListElement{
fame:"Element5"
ListElement{
fame:"Element6"
Component
id:comp1
Rectangle
width:50
height:50
color:"red"
border.width: 2
border.color: "black"
Text {
text: name
MouseArea {
anchors.fill: parent
onClicked: {
console.log("entering assigning model")
mylistview.model=model2
mylistview.delegate=comp2
Component
id:comp2
Rectangle
width:50
height:50
color:"blue"
border.width: 2
border.color: "black"
Text {
text: fame
MouseArea {
anchors.fill: parent
onClicked: {
console.log("entering assigning model")
mylistview.delegate=comp1
mylistview.model=model1
ListView
id:mylistview
anchors.fill: parent
model:model1
delegate: comp1
////////////////////////////////////
To copy to clipboard, switch view to plain text mode
Looks like you forgot the "assign undefined" part suggested above.
But then again, why worry about such a transient "error"
Cheers,
When i am trying to access the data of the second model from the mouse click , it is not happening , it cannot access the model data.
Can you also suggest how can i assign undefined to a delegate.
I tried something like this
mylistview.delegate = undefined
But this did not work out
What does "not work out" mean?
If it can't do the assignment, you could try an "empty" delegate component, i.e. a component with just an empty Item{}
Cheers,
Thank you for the reply
I tried the above suggestions but again the reference error issue , now the mylistview itself is not available.
Below is the whole code which i tried:
Qt Code:
Switch view
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
visible: true
Component{
id:emptycomp
Item{}
}
ListModel{
id:model1
ListElement{
name:"Element1"
}
ListElement{
name:"Element2"
}
ListElement{
name:"Element3"
}
}
ListModel{
id:model2
ListElement{
fame:"Element4"
}
ListElement{
fame:"Element5"
}
ListElement{
fame:"Element6"
}
}
Component
{
id:comp1
Row{
Rectangle
{
width:50
height:50
color:"red"
border.width: 2
border.color: "black"
Text {
text: name
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log("entering assigning model")
mylistview.delegate=emptycomp
mylistview.model=model2
mylistview.delegate=comp2
}
}
}
}
}
Component
{
id:comp2
Row{
Rectangle
{
width:50
height:50
color:"blue"
border.width: 2
border.color: "black"
Text {
text: fame
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log("entering assigning model")
mylistview.delegate=emptycomp
mylistview.delegate=comp1
mylistview.model=model1
}
}
}
}
}
ListView
{
id:mylistview
anchors.fill: parent
model:model1
delegate: comp1
}
}
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
visible: true
Component{
id:emptycomp
Item{}
ListModel{
id:model1
ListElement{
name:"Element1"
ListElement{
name:"Element2"
ListElement{
name:"Element3"
ListModel{
id:model2
ListElement{
fame:"Element4"
ListElement{
fame:"Element5"
ListElement{
fame:"Element6"
Component
id:comp1
Rectangle
width:50
height:50
color:"red"
border.width: 2
border.color: "black"
Text {
text: name
MouseArea {
anchors.fill: parent
onClicked: {
console.log("entering assigning model")
mylistview.delegate=emptycomp
mylistview.model=model2
mylistview.delegate=comp2
Component
id:comp2
Rectangle
width:50
height:50
color:"blue"
border.width: 2
border.color: "black"
Text {
text: fame
MouseArea {
anchors.fill: parent
onClicked: {
console.log("entering assigning model")
mylistview.delegate=emptycomp
mylistview.delegate=comp1
mylistview.model=model1
ListView
id:mylistview
anchors.fill: parent
model:model1
delegate: comp1
To copy to clipboard, switch view to plain text mode