Can an onClicked() be a property?
-
@mzimmers
override this func
QVariant QAbstractItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const;
then you can map QList to a QML ListView. -
Hi all -
My app uses a customized list. Here's the minimum of it:
// Roundlist.qml Rectangle { // list background property alias model: listView.model Component { id: listDelegate Rectangle { ... MouseArea { onClicked: { /* I'd like to put something here */ } } } } ListView { id: listView delegate: listDelegate } }
I use this list like so:
ListModel { id: zoneDetailModel ListElement { parameter: "text1"; value: "value1"} ListElement { parameter: "text2"; value: "value2"} ListElement { parameter: "text3"; value: "value3"} } Roundlist { model: zoneNameModel }
Is there a way to designate an action for the onClicked() in my model? If not, is there another way to accomplish this?
Thanks...
// Roundlist.qml Rectangle { // list background property alias model: listView.model signal doClick(ind index) Component { id: listDelegate Rectangle { ... MouseArea { onClicked: { doClick(index) } } } } ListView { id: listView delegate: listDelegate } }
Then use:
ListModel { id: zoneDetailModel ListElement { parameter: "text1"; value: "value1"; funcIndex: 0} ListElement { parameter: "text2"; value: "value2"; funcIndex: 1} ListElement { parameter: "text3"; value: "value3"; funcIndex: 2} } property var funcs: [ function(){ //do stuff}, function(){ //do stuff}, function(){ //do stuff}, ] Roundlist { model: zoneNameModel onDoClick: { funcs[index]() } }
You could also pass a parameter if you really want via the signal.
You cannot put a function like this in your model. That won't work with ListModel. You have to have a separate structure to point to the function. You could define your functions outside the list as well and reference by name. -
// Roundlist.qml Rectangle { // list background property alias model: listView.model signal doClick(ind index) Component { id: listDelegate Rectangle { ... MouseArea { onClicked: { doClick(index) } } } } ListView { id: listView delegate: listDelegate } }
Then use:
ListModel { id: zoneDetailModel ListElement { parameter: "text1"; value: "value1"; funcIndex: 0} ListElement { parameter: "text2"; value: "value2"; funcIndex: 1} ListElement { parameter: "text3"; value: "value3"; funcIndex: 2} } property var funcs: [ function(){ //do stuff}, function(){ //do stuff}, function(){ //do stuff}, ] Roundlist { model: zoneNameModel onDoClick: { funcs[index]() } }
You could also pass a parameter if you really want via the signal.
You cannot put a function like this in your model. That won't work with ListModel. You have to have a separate structure to point to the function. You could define your functions outside the list as well and reference by name.@fcarney very understandable; thanks. A couple questions:
- instead ofthe explicit funcIndex values, can the call to doClick() somehow extract the index of the zoneDetailModel? That would make the implementation just a bit cleaner.
- If my "do stuff" is just to display a new screen, or produce a popup, how do I proceduralize that?
Thanks...this is really helpful.
-
@fcarney very understandable; thanks. A couple questions:
- instead ofthe explicit funcIndex values, can the call to doClick() somehow extract the index of the zoneDetailModel? That would make the implementation just a bit cleaner.
- If my "do stuff" is just to display a new screen, or produce a popup, how do I proceduralize that?
Thanks...this is really helpful.
-
@fcarney very understandable; thanks. A couple questions:
- instead ofthe explicit funcIndex values, can the call to doClick() somehow extract the index of the zoneDetailModel? That would make the implementation just a bit cleaner.
- If my "do stuff" is just to display a new screen, or produce a popup, how do I proceduralize that?
Thanks...this is really helpful.
@mzimmers said in Can an onClicked() be a property?:
If my "do stuff" is just to display a new screen, or produce a popup, how do I proceduralize that?
I would use a state for that. There are all kinds of state things that can call functions and set properties on things. That is how we do dialog boxes is with states.
-
@mzimmers said in Can an onClicked() be a property?:
If my "do stuff" is just to display a new screen, or produce a popup, how do I proceduralize that?
I would use a state for that. There are all kinds of state things that can call functions and set properties on things. That is how we do dialog boxes is with states.
If the list is static it doesn't need to be a
ListModel
, you could then have a function directly in the model:ListView { model: [ { parameter: "text1", value: "value1", action: () => { doStuf(1) }}, { parameter: "text2", value: "value2", action: () => { doStuf(2) }}, { parameter: "text3", value: "value3", action: () => { doStuf(3) }} ] delegate: Item { // ... TapHandler { onTapped: modelData.action() } } }
-
If the list is static it doesn't need to be a
ListModel
, you could then have a function directly in the model:ListView { model: [ { parameter: "text1", value: "value1", action: () => { doStuf(1) }}, { parameter: "text2", value: "value2", action: () => { doStuf(2) }}, { parameter: "text3", value: "value3", action: () => { doStuf(3) }} ] delegate: Item { // ... TapHandler { onTapped: modelData.action() } } }
-
M mzimmers has marked this topic as solved on
-
M mzimmers has marked this topic as unsolved on
-
// Roundlist.qml Rectangle { // list background property alias model: listView.model signal doClick(ind index) Component { id: listDelegate Rectangle { ... MouseArea { onClicked: { doClick(index) } } } } ListView { id: listView delegate: listDelegate } }
Then use:
ListModel { id: zoneDetailModel ListElement { parameter: "text1"; value: "value1"; funcIndex: 0} ListElement { parameter: "text2"; value: "value2"; funcIndex: 1} ListElement { parameter: "text3"; value: "value3"; funcIndex: 2} } property var funcs: [ function(){ //do stuff}, function(){ //do stuff}, function(){ //do stuff}, ] Roundlist { model: zoneNameModel onDoClick: { funcs[index]() } }
You could also pass a parameter if you really want via the signal.
You cannot put a function like this in your model. That won't work with ListModel. You have to have a separate structure to point to the function. You could define your functions outside the list as well and reference by name.@fcarney I implemented your suggestion like so:
ListModel { id: zoneDetailModel ListElement { parameter: "param0"; value: "value0"; funcIndex: 0 } ListElement { parameter: "param1"; value: "value1"; funcIndex: 1 } ListElement { parameter: "param2"; value: "value2"; funcIndex: 2 } } property var funcs: [ function() { console.log("0!") }, function() { console.log("1!") }, function() { console.log("2!") }, ] Roundlist { id: detailList width: newZone.width - (scroller.width * 2) model: zoneDetailModel onDoClick: { funcs[index]() } }
It seems to work, though the first time I click on one of the items, I get this:
qt.qml.context: qrc:/nga_demo/Newzone.qml:68:13 Parameter "index" is not declared. Injection of parameters into signal handlers is deprecated. Use JavaScript functions with formal parameters instead.
Is this something that can be dealt with?
BTW: I believe that this line:
signal doClick(ind index)
should be:
signal doClick(int index)
yes?
Thanks...
-
@fcarney I implemented your suggestion like so:
ListModel { id: zoneDetailModel ListElement { parameter: "param0"; value: "value0"; funcIndex: 0 } ListElement { parameter: "param1"; value: "value1"; funcIndex: 1 } ListElement { parameter: "param2"; value: "value2"; funcIndex: 2 } } property var funcs: [ function() { console.log("0!") }, function() { console.log("1!") }, function() { console.log("2!") }, ] Roundlist { id: detailList width: newZone.width - (scroller.width * 2) model: zoneDetailModel onDoClick: { funcs[index]() } }
It seems to work, though the first time I click on one of the items, I get this:
qt.qml.context: qrc:/nga_demo/Newzone.qml:68:13 Parameter "index" is not declared. Injection of parameters into signal handlers is deprecated. Use JavaScript functions with formal parameters instead.
Is this something that can be dealt with?
BTW: I believe that this line:
signal doClick(ind index)
should be:
signal doClick(int index)
yes?
Thanks...
@mzimmers said in Can an onClicked() be a property?:
Injection of parameters into signal handlers is deprecated.
I searched on "Injection of parameters into signal handlers is deprecated."
-
@mzimmers said in Can an onClicked() be a property?:
Injection of parameters into signal handlers is deprecated.
I searched on "Injection of parameters into signal handlers is deprecated."
@fcarney ah yes, my old friend the lambda.
Roundlist { id: detailList width: newZone.width - (scroller.width * 2) model: zoneDetailModel onDoClick: (index)=> { funcs[index]() } }
This eliminated the error, and works fine.
Lambdas still look weird to me, though...
Thanks for the help.
-
M mzimmers has marked this topic as solved on