c++ - How to display values from lists in a UI QML (QT) inside a Repeater -
i've been facing issue days without coming conclusion, hope give me useful hints solve it.
i'll try simplify issue example:
- in c++ code defined class myobjectmodel act later model in repeater block in main ui.qml file. myobjectmodel visible qqmlapplicationengine.
- myobjectmodel has 2 attributes (lists) : xcoordinateslist , ycoordinateslist. represent x , y pixel coordinates of list of points. i.e. xcoordinateslist = [100, 200], ycoordinateslist = [10, 20] mean logically have 2 points following pixel coordinates want display on screen: (100,10), (10,20).
the xcoordinateslist , ycoordinateslist roles of model qml engine. means instance in common .qml file can print content of xcoordinateslist typing:
component.oncompleted { console.log("x coordinates: ",xcoordinateslist); }
the question is: how can display @ same time list of points on screen?
if want display 1 dot (so 1 couple of coordinates) code works. don't know how extend make print of them.
in mainform.ui.qml defined repeater inside rectangle :
rectangle { .... repeater { model: dotmodel delegate: dotitem { id: dotitem; objectname: "dotitem"; dotpositiononmap { id: dotpositionid; objectwidth: dotitem.width; objectheight: dotitem.height; } x: dotpositionid.xpositiononmap; y: dotpositionid.ypositiononmap; } } .... }
i need repeater because myobjectmodel holds 2 lists of x , y coordinates can dynamically change on time. dotmodel fake model use other purpose. dotitem qml item identifies red dot circle image want depict on screen each couple of elements in xcoordinateslist, ycoordinateslist.
dotitem.ui.qml
import qtquick 2.4 import qtquick.layouts 1.1 item { width: 10 height: 10 opacity: 1 image { id: dotitemimage anchors.fill: parent source: "red_dot.png" } }
red_dot.png image should displayed each point depicted on screen.
dotpositiononmap.qml responsible computing right x , y pixel position on screen.
import qtquick 2.5 import "calccurrentpos_script.js" currentpos item { // values filled mainform.ui.qml property int objectwidth property int objectheight // getting current coordinates // fetching element 0 both lists property real currentx: currentpos.getcurrentxpoint(0); property real currenty: currentpos.getcurrentypoint(0); // generating x , y pixel position on map. // toy example property int xpositiononmap : currentx-(objectwidth/2); property int ypositiononmap : currenty-(objectheight/2); }
where calccurrentpos_script.js
function getcurrentxpoint(val) { return xcoordinateslist[val]; } function getcurrentypoint(val) { return ycoordinateslist[val]; }
in way can display 1 dot on screen since specify in dotpositiononmap.qml point fetch:
// fetching element 0 in case property real currentx: currentpos.getcurrentxpoint(0); property real currenty: currentpos.getcurrentypoint(0);
i used javascript attempt because thought use for loop scan elements displayed, didn't work.
extract of model
qvariant mymodelobject::data(const qmodelindex& index, int role) const { const mymodelobject& object = objects.values().value(index.row()); .... if(role == xrole) { qlist<trackpoint> tkrlist = object.getlist(); qlist<qvariant> tkrvariantlist; for(auto track: trackpointlist) { tkrvariantlist.append(track.getposition().getx()); } return qvariant(tkrvariantlist); } else if(role == yrole) { qlist<trackpoint> tkrlist = object.getlist(); qlist<qvariant> tkrvariantlist; for(auto track: trackpointlist) { tkrvariantlist.append(track.getposition().gety()); } return qvariant(tkrvariantlist); } } .... .... qhash<int, qbytearray> mymodelobject::rolenames() const { qhash<int, qbytearray> roles; roles[xrole] = "xcoordinateslist"; roles[yrole] = "ycoordinateslist"; return roles; }
i appreciate ideas concerning generalisation of implementation.
thank you
the qt documentation clear. first have read that article. think in case simpliest way list-based model. or, of cource, can subclass qabstractlistmodel.
your question not clear , didn't provide code of model maybe small example you:
declaration
class mymodel : public qabstractlistmodel { q_object public: enum pointroles { xrole = qt::userrole + 1, yrole }; mymodel(qobject *parent = q_nullptr); int rowcount(const qmodelindex &parent = qmodelindex()) const; qvariant data(const qmodelindex &index, int role = qt::displayrole) const; qhash<int, qbytearray> rolenames() const; private: qlist<qpoint> m_list; };
implementation
mymodel::mymodel(qobject *parent) : qabstractlistmodel(parent) { } qhash<int, qbytearray> mymodel::rolenames() const { qhash<int, qbytearray> roles; roles[xrole] = "xcoord"; roles[yrole] = "ycoord"; return roles; } int mymodel::rowcount(const qmodelindex &parent) const { q_unused(parent); return m_list.count(); } qvariant mymodel::data(const qmodelindex &index, int role) const { if(role == xrole) return m_list[index.row()].x(); else if(role == yrole) return m_list[index.row()].y(); return qvariant(); }
registation
qmlregistertype<mymodel>("qt.test", 1, 0, "pointmodel");
usage
window { visible: true width: 800 height: 800 pointmodel {id: mymodel} repeater { model: mymodel delegate: rectangle { x: 100 + xcoord y: 100 + ycoord width: 20 height: 20 color: "red" radius: 10 } } }
Comments
Post a Comment