Chosing `contentItem` on condition
-
Hello everyone,
I just learnt how to load a component from an external QML file, now I would like to be able to dynamically decide which to load among a few options.Let's say I have files
// BuysItem.qml Rectangle {...}
and
// EmployeeItem.qml Rectangle {...}
Now if I do
ListView { delegate: ItemDelegate { contentItem: BuysItem {} } }
or
ListView { delegate: ItemDelegate { contentItem: EmployeeItem {} }
I see the correct item, but now I want to be able to choose which one to use based on the value of some other variable.
I have triedListView { delegate: ItemDelegate { contentItem: projList.currentType == "Buys" ? BuysItem {} : EmployeeItem {} }
which gives
Syntax error
, andListView { delegate: ItemDelegate { function getContentItem() { if(projList.currentType == "Buys") { return BuysItem {} } if(projList.currentType == "Employee") { return EmployeeItem {} } } contentItem: getContentItem() }
which gives
Expected token ';'
on thereturn
statements.I think it's a syntax error, what is the correct way to do this?
Also, where can I learn this stuff [syntax and the like] so that I don't have to ask here ever two lines of code I write?
Thanks!
-
Hello everyone,
I just learnt how to load a component from an external QML file, now I would like to be able to dynamically decide which to load among a few options.Let's say I have files
// BuysItem.qml Rectangle {...}
and
// EmployeeItem.qml Rectangle {...}
Now if I do
ListView { delegate: ItemDelegate { contentItem: BuysItem {} } }
or
ListView { delegate: ItemDelegate { contentItem: EmployeeItem {} }
I see the correct item, but now I want to be able to choose which one to use based on the value of some other variable.
I have triedListView { delegate: ItemDelegate { contentItem: projList.currentType == "Buys" ? BuysItem {} : EmployeeItem {} }
which gives
Syntax error
, andListView { delegate: ItemDelegate { function getContentItem() { if(projList.currentType == "Buys") { return BuysItem {} } if(projList.currentType == "Employee") { return EmployeeItem {} } } contentItem: getContentItem() }
which gives
Expected token ';'
on thereturn
statements.I think it's a syntax error, what is the correct way to do this?
Also, where can I learn this stuff [syntax and the like] so that I don't have to ask here ever two lines of code I write?
Thanks!
Component { id: buysItem BuysItem {} } Component { id: employeeItem EmployeeItem {} } ListView { delegate: ItemDelegate { id: delegate contentItem: { switch( projList.currentType ) { case "Buys": return buysItem.createObject(delegate); case "Employee": return employeeItem.createObject(delegate); } } } }
or alternatively:
ListView { delegate: ItemDelegate { contentItem: Loader { sourceComponent: { switch( projList.currentType ) { case "Buys": return "qrc:/qml/BuysItem.qml" case "Employee": return "qrc:/qml/EmployeeItem.qml" } } } } }
(untested)
-
Hi, thanks for your help!
I tried both your solutions, with the first one I get aReferenceError: model is not defined
inside the external component, at the lines where I access the data in theListView
model.
The second one complains sayingUnable to assign QString to QQmlComponent*
, presumably on thereturn
statement inside theswitch
. -
Hi, thanks for your help!
I tried both your solutions, with the first one I get aReferenceError: model is not defined
inside the external component, at the lines where I access the data in theListView
model.
The second one complains sayingUnable to assign QString to QQmlComponent*
, presumably on thereturn
statement inside theswitch
.@mleoni said in Chosing `contentItem` on condition:
with the first one I get a ReferenceError: model is not defined inside the external component, at the lines where I access the data in the ListView model.
there is no appearance of "model" in my code. So that one comes from your code.
But why do you need to access the model directly?! Your model should expose its data via roles (see QAbstractItemModel::roleNames())@mleoni said in Chosing `contentItem` on condition:
The second one complains saying Unable to assign QString to QQmlComponent*, presumably on the return statement inside the switch.
my fault. change
sourceComponent
tosource
-
@mleoni said in Chosing `contentItem` on condition:
with the first one I get a ReferenceError: model is not defined inside the external component, at the lines where I access the data in the ListView model.
there is no appearance of "model" in my code. So that one comes from your code.
But why do you need to access the model directly?! Your model should expose its data via roles (see QAbstractItemModel::roleNames())@mleoni said in Chosing `contentItem` on condition:
The second one complains saying Unable to assign QString to QQmlComponent*, presumably on the return statement inside the switch.
my fault. change
sourceComponent
tosource
@raven-worx said in Chosing `contentItem` on condition:
my fault. change
sourceComponent
tosource
Ok, now it works better!
@raven-worx said in Chosing `contentItem` on condition:
there is no appearance of "model" in my code. So that one comes from your code.
But why do you need to access the model directly?! Your model should expose its data via roles (see QAbstractItemModel::roleNames())It's true. My components look like this.
Rectangle { Text { text: model.date } }
where
model
is the model defined in theListView
anddate
is a role that I defined in the C++ implementation where I override the function that you mentioned.In particular, in the C++ code I inherit
QAbstractListModel
and reimplementrowCount
,roleNames
anddata
, then instantiate it and useengine.rootContext()->setContextProperty
to expose it to QML, where I use the instance as a model, and then access, for example,model.date
wheredate
was defined inroleNames
. Is this a bad approach? Can you suggest any better one? -
@raven-worx said in Chosing `contentItem` on condition:
my fault. change
sourceComponent
tosource
Ok, now it works better!
@raven-worx said in Chosing `contentItem` on condition:
there is no appearance of "model" in my code. So that one comes from your code.
But why do you need to access the model directly?! Your model should expose its data via roles (see QAbstractItemModel::roleNames())It's true. My components look like this.
Rectangle { Text { text: model.date } }
where
model
is the model defined in theListView
anddate
is a role that I defined in the C++ implementation where I override the function that you mentioned.In particular, in the C++ code I inherit
QAbstractListModel
and reimplementrowCount
,roleNames
anddata
, then instantiate it and useengine.rootContext()->setContextProperty
to expose it to QML, where I use the instance as a model, and then access, for example,model.date
wheredate
was defined inroleNames
. Is this a bad approach? Can you suggest any better one?@mleoni said in Chosing `contentItem` on condition:
text: model.date
since you already implemented roleNames() in your model, simply use
text: date
instead oftext: model.date
Each delegate instance then has the value for the corresponding index set in the variable with the name from roleNames() -
If I take out
model
I getReferenceError: date is not defined
.Meanwhile, the second solution seems to work well so let me thank you for that at least!
@mleoni said in Chosing `contentItem` on condition:
If I take out model I get ReferenceError: date is not defined.
maybe only the delegate component gets the data set, i don't know now, it may be.
So try to forward it from the root delegate item to your child items