Can an onClicked() be a property?
-
The way I would do it is to add a signal to Roundlist{}. clicked, activated. Something. Either that or alias the currentIndex property from the ListView, if the click will indeed change the view's currentIndex. Connect to the signal where Roundlist is instantiated, and perform the desired computation there.
You could also add a var property to Roundlist, and attempt to invoke it as a function.
-
Hi
I would do something like this:Component { id: listDelegate Rectangle { ... MouseArea { onClicked: { myClick(componentParameter, componentValue /* or the index*/) /* I'd like to put something here */ }
signal myClick(parameter, value /*or the index*/) onMycliked: function(parameter, value /*, index*/) { if (parameter === "text1" ) //or use value1 or index { doSomething1() } if (parameter === "text2" ) //or use value2 or index { doSomething2() } ........ }
-
Hi
I would do something like this:Component { id: listDelegate Rectangle { ... MouseArea { onClicked: { myClick(componentParameter, componentValue /* or the index*/) /* I'd like to put something here */ }
signal myClick(parameter, value /*or the index*/) onMycliked: function(parameter, value /*, index*/) { if (parameter === "text1" ) //or use value1 or index { doSomething1() } if (parameter === "text2" ) //or use value2 or index { doSomething2() } ........ }
Thanks for the replys, guys. @johngod: Roundlist.qml is intended to be a reusable module. I can't code the doSomethingN() in it, as each list, as well as each list element, may have a unique click handler.
@jeremy_k: I don't see a way around passing some information about the click handler to Roundlist. Can you elaborate on this:
You could also add a var property to Roundlist, and attempt to invoke it as a function.
Thanks.
-
Thanks for the replys, guys. @johngod: Roundlist.qml is intended to be a reusable module. I can't code the doSomethingN() in it, as each list, as well as each list element, may have a unique click handler.
@jeremy_k: I don't see a way around passing some information about the click handler to Roundlist. Can you elaborate on this:
You could also add a var property to Roundlist, and attempt to invoke it as a function.
Thanks.
@mzimmers said in Can an onClicked() be a property?:
Roundlist.qml is intended to be a reusable module. I can't code the doSomethingN() in it, as each list, as well as each list element, may have a unique click handler.
Well that was my ideia, define the signal myClick inside RoundList, and invoke it in mouse click passing the list element unique identifier. Then implement myClick signal handler outside, where ever the reusable component is instanciated, or create connections, whatever. Then again I not sure what you are trying to code in the mouse click handler, so I dont have the big picture.
-
Thanks for the replys, guys. @johngod: Roundlist.qml is intended to be a reusable module. I can't code the doSomethingN() in it, as each list, as well as each list element, may have a unique click handler.
@jeremy_k: I don't see a way around passing some information about the click handler to Roundlist. Can you elaborate on this:
You could also add a var property to Roundlist, and attempt to invoke it as a function.
Thanks.
-
@mzimmers said in Can an onClicked() be a property?:
Roundlist.qml is intended to be a reusable module. I can't code the doSomethingN() in it, as each list, as well as each list element, may have a unique click handler.
Well that was my ideia, define the signal myClick inside RoundList, and invoke it in mouse click passing the list element unique identifier. Then implement myClick signal handler outside, where ever the reusable component is instanciated, or create connections, whatever. Then again I not sure what you are trying to code in the mouse click handler, so I dont have the big picture.
@johngod said in Can an onClicked() be a property?:
Then again I not sure what you are trying to code in the mouse click handler, so I dont have the big picture.
Nothing fancy - just move to a new screen (in some cases a popup).
I don't understand the part of your idea where you use the doSomething1, doSomething2, etc. Those can't be hard-coded functions.
-
@johngod said in Can an onClicked() be a property?:
Then again I not sure what you are trying to code in the mouse click handler, so I dont have the big picture.
Nothing fancy - just move to a new screen (in some cases a popup).
I don't understand the part of your idea where you use the doSomething1, doSomething2, etc. Those can't be hard-coded functions.
-
@mzimmers Is it easier to create a C++ model for it? And simply call a func(Index) in the model and do what you want in this func. Actually you may add more features later on and a C++ model may help a bit. I coded it that way.
@JoeCFD eventually this will use a C++ model for sure; I was just trying to start with something simple. I actually already have a C++ model for my zone list:
// this is the definition of the class for an individual zone. class Zone { Q_GADGET Q_PROPERTY(QString name MEMBER m_name) QUuid m_uuid; QString m_name; public: Zone(const QString &name = QString()); QString name() const { return m_name; } void setName(QString name) { m_name = name; } bool operator==(const Zone &rhs) const; }; typedef QList<Zone> zoneList; // this is the definition of the class for a list of zones. class ZoneModel: public QAbstractListModel { Q_OBJECT Q_PROPERTY(zoneList *list READ list WRITE setList NOTIFY listChanged) enum { NameRole = Qt::UserRole, }; zoneList *m_list; ...
Currently my Zone class has just two members, but eventually there will be several more. The QML list I'm creating is intended to represent each of these members. When the user clicks on an item in the list, the idea would be that he can then edit that item. Is it possible to map a QList to a QML ListView?
(My Roundlist is just some formatting behind the list; the guts of Roundlist uses a ListView.)
Thanks...
-
@JoeCFD eventually this will use a C++ model for sure; I was just trying to start with something simple. I actually already have a C++ model for my zone list:
// this is the definition of the class for an individual zone. class Zone { Q_GADGET Q_PROPERTY(QString name MEMBER m_name) QUuid m_uuid; QString m_name; public: Zone(const QString &name = QString()); QString name() const { return m_name; } void setName(QString name) { m_name = name; } bool operator==(const Zone &rhs) const; }; typedef QList<Zone> zoneList; // this is the definition of the class for a list of zones. class ZoneModel: public QAbstractListModel { Q_OBJECT Q_PROPERTY(zoneList *list READ list WRITE setList NOTIFY listChanged) enum { NameRole = Qt::UserRole, }; zoneList *m_list; ...
Currently my Zone class has just two members, but eventually there will be several more. The QML list I'm creating is intended to represent each of these members. When the user clicks on an item in the list, the idea would be that he can then edit that item. Is it possible to map a QList to a QML ListView?
(My Roundlist is just some formatting behind the list; the guts of Roundlist uses a ListView.)
Thanks...
-
@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