Page 2 of 2 FirstFirst 12
Results 21 to 24 of 24

Thread: QML ListModel for interaction with C++

  1. #21
    Join Date
    Nov 2011
    Posts
    26
    Thanks
    6
    Thanked 3 Times in 3 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded Qt Jambi
    Platforms
    Unix/X11 Windows

    Default Re: QML ListModel for interaction with C++

    You have QDeclarativeItem instances all over your code, just take a look.
    This is the structure that works for me by now:
    Qt Code:
    1. class QMLPtrAbstractItem : public QObject
    2. {
    3. Q_OBJECT
    4. public:
    5. virtual ~QMLPtrAbstractItem() { }
    6.  
    7. virtual bool setData(int role, const QVariant &value) = 0;
    8. virtual QVariant getData(int role) const = 0;
    9.  
    10. virtual int getUID() const = 0;
    11. virtual void setUID(int uid) = 0;
    12. };
    13.  
    14. class EmpData : public QMLPtrAbstractItem
    15. {
    16. Q_OBJECT
    17. public:
    18. enum EmpRoles {
    19. Name = Qt::UserRole + 1,
    20. UID,
    21. Qualification
    22. };
    23.  
    24. static QHash<int, QByteArray> getQMLRoles(){
    25. QHash<int, QByteArray> roles;
    26. roles[Name] = "name";
    27. roles[UID] = "uid";
    28. roles[Qualification] = "qualification";
    29. return roles;
    30. }
    31.  
    32. EmpData() {}
    33.  
    34. virtual QVariant getData(int role) const {
    35. if (role == Name)
    36. return getName();
    37. else if (role == UID)
    38. return getUID();
    39. else if (role == Qualification)
    40. return getQualification();
    41. return QVariant();
    42. }
    43.  
    44. virtual bool setData(int role, const QVariant &value) {
    45. bool changed = false;
    46. if (role == Name){
    47. changed = true;
    48. setName(value.toString());
    49. }
    50. else if (role == UID){
    51. changed = true;
    52. setUID(value.toInt());
    53. }
    54. else if (role == Qualification){
    55. changed = true;
    56. setQualification(value.toString());
    57. }
    58. return changed;
    59. }
    60.  
    61. private:
    62. .....
    63. };
    64.  
    65. class TaskData : public QMLPtrAbstractItem
    66. {
    67. Q_OBJECT
    68.  
    69. public:
    70. enum TaskRoles {
    71. UID = Qt::UserRole + 1,
    72. Name,
    73. BgColor1,
    74. BgColor2,
    75. XPos,
    76. YPos,
    77. Length,
    78. CreationUser,
    79. OrderType,
    80. Active,
    81. Index
    82. };
    83.  
    84. static QHash<int, QByteArray> getQMLRoles(){
    85. QHash<int, QByteArray> roles;
    86. roles[UID] = "uid";
    87. roles[Name] = "name";
    88. roles[BgColor1] = "bgColor1";
    89. roles[BgColor2] = "bgColor2";
    90. roles[XPos] = "xPos";
    91. roles[YPos] = "yPos";
    92. roles[Length] = "length";
    93. roles[CreationUser] = "creationuser";
    94. roles[OrderType] = "orderType";
    95. roles[Active] = "active";
    96. roles[Index] = "index";
    97. return roles;
    98. }
    99.  
    100. TaskData() {
    101. _bgcolor1 = "#FEFEFE";
    102. _bgcolor2 = "#ededeb";
    103. _active = false;
    104. }
    105. virtual ~TaskData() { }
    106.  
    107. .....
    108.  
    109. QVariant getData(int role) const {
    110. if (role == UID)
    111. return getUID();
    112. else if (role == Name)
    113. return getName();
    114. else if (role == BgColor1)
    115. return getBgColor1();
    116. else if (role == BgColor2)
    117. return getBgColor2();
    118. else if (role == XPos)
    119. return getXPos();
    120. else if (role == YPos)
    121. return getYPos();
    122. else if (role == Length)
    123. return getLength();
    124. else if (role == CreationUser)
    125. return getCreationUser();
    126. else if (role == OrderType)
    127. return getOrderType();
    128. else if (role == Active)
    129. return isActive();
    130. else if (role == Index)
    131. return getIndex();
    132. return QVariant();
    133. }
    134.  
    135. bool setData(int role, const QVariant &value) {
    136. bool changed = false;
    137. if (role == UID){
    138. changed = true;
    139. setUID(value.toInt());
    140. }
    141. else if (role == Name){
    142. changed = true;
    143. setName(value.toString());
    144. }
    145. else if (role == BgColor1){
    146. changed = true;
    147. setBgColor1(value.toString());
    148. }
    149. else if (role == BgColor2){
    150. changed = true;
    151. setBgColor2(value.toString());
    152. }
    153. else if (role == XPos){
    154. changed = true;
    155. setXPos(value.toInt());
    156. }
    157. else if (role == YPos){
    158. changed = true;
    159. setYPos(value.toInt());
    160. }
    161. else if (role == Length){
    162. changed = true;
    163. setLength(value.toInt());
    164. }
    165. else if (role == CreationUser){
    166. changed = true;
    167. setCreationUser(value.toInt());
    168. }
    169. else if (role == OrderType){
    170. changed = true;
    171. setOrderType(value.toInt());
    172. }
    173. else if (role == Active){
    174. changed = true;
    175. setActive(value.toInt());
    176. }
    177. else if (role == Index){
    178. changed = true;
    179. setIndex(value.toInt());
    180. }
    181. return changed;
    182. }
    183.  
    184. private:
    185. ....
    186. };
    187.  
    188. class OrderData : public TaskData
    189. {
    190. Q_OBJECT
    191. ....
    192. }
    193.  
    194. class EventData : public TaskData
    195. {
    196. Q_OBJECT
    197. ...
    198. }
    199.  
    200. class QMLPtrNotificationModel : public QAbstractListModel
    201. {
    202. Q_OBJECT
    203. ....
    204. }
    205.  
    206. QVariant QMLPtrNotificationModel::data(const QModelIndex &index, int role) const
    207. {
    208. if (index.row() < 0 || index.row() > lst.size())
    209. return QVariant();
    210.  
    211. const QMLPtrAbstractItem * const ptrItem = lst[index.row()];
    212.  
    213. return ptrItem->getData(role);
    214. }
    215.  
    216. bool QMLPtrNotificationModel::setData(const QModelIndex &index, const QVariant &value, int role)
    217. {
    218. if (index.row() >= 0 && index.row() < lst.size()) {
    219.  
    220. QMLPtrAbstractItem * const ptrItem = lst.at(index.row());
    221. if(ptrItem){
    222. bool changed = ptrItem->setData(role, value);
    223.  
    224. if(changed)
    225. emit dataChanged(index, index);
    226. return changed;
    227. }
    228. return false;
    229. }else
    230. qDebug() << "QMLPtrNotificationModel::setData( " << role << ")";
    231.  
    232. return false;
    233. }
    To copy to clipboard, switch view to plain text mode 

    QML looks like that:
    Qt Code:
    1. Repeater {
    2. id: tasks
    3. model: taskModel // is registered via context() - holds OrderData and EventData via virtual binding
    4. delegate: TaskData { }
    5. }
    To copy to clipboard, switch view to plain text mode 


    There is no QDeclarativeItem anymore - and it compiles and works
    Different model instances of what?
    Different Model instances: one for OrderData, one for EventData and one for EmpData

    As i think the code will also work if i rename the classes to *Cpp? They just have the same names as the delegates - The QML delegate gets the
    Data from the Model provided in the Repeater via accessing the roles of the model?!

    TaskData.qml:
    Qt Code:
    1. Text {
    2. id: taskName
    3. anchors.centerIn: parent
    4. text: name; // sets the name as text -> accesses the given model and executes data() for the role "name" which returns the name !?
    5. color: "white";
    6. }
    To copy to clipboard, switch view to plain text mode 

    Where is my structural error? =(

    -------------------

    I tried it by renamin the classes to *Cpp - works either
    Qt Code:
    1. class EmpDataCpp : public QMLPtrAbstractItem { ... }
    2. class TaskDataCpp : public QMLPtrAbstractItem { ... }
    3. class OrderDataCpp : public TaskDataCpp { .. .}
    4. class EventDataCpp : public TaskDataCpp { .. .}
    To copy to clipboard, switch view to plain text mode 

    With Delegates:
    Qt Code:
    1. Repeater {
    2. id: empGrid
    3. model: empModel
    4. delegate: Employee { }
    5. }
    6. Repeater {
    7. id: tasks
    8. model: taskModel
    9. delegate: TaskData { }
    10. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by shock; 21st March 2012 at 21:32. Reason: Tried with renaming classes to *Cpp

  2. #22
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QML ListModel for interaction with C++

    You are making it much more complicated than it needs to be. The item class needs not inherit QObject since you are not using any QObject related functionality in it. Next thing is that your model doesn't do anything fancy, it has functionality similar to QStandardItemModel, so you can use that instead of a custom model you need to care about. Third of all if you really insist on using a custom model class, there is no point in having various subclasses of QMLPtrAbstractItem because neither of these subclasses add anything to their base class functionality. Fourth of all if you get rid of QObject legacy, you can use objects instead of pointers to objects in your model which reduces possibilities of making an error somewhere in code.

    Currently your code is equivalent to:

    Qt Code:
    1. class MyModel : public QStandardItemModel {
    2. public:
    3. MyModel(QObject *parent = 0) : QStandardItemModel(parent) { setColumnCount(1); }
    4. void setRoles(const QHash<int, QByteArray> & roleNames) { setRoleNames(roleNames); }
    5. };
    6.  
    7. enum EmpRoles { Name = Qt::DisplayRole, UID = Qt::UserRole, Qualification };
    8. enum TaskRoles { Name = Qt::DisplayRole, UID = Qt::UserRole, ... }
    9. QHash<int, QByteArray> empNames;
    10. empNames[EmpRoles::Name] = "name";
    11. empNames[EmpRoles::UID] = "uid";
    12. // etc.
    13. MyModel empModel;
    14. empModel.setRoles(empNames);
    15.  
    16.  
    17.  
    18. QHash<int, QByteArray> taskNames;
    19. taskNames[TaskRoles::Name] = "name";
    20. taskNames[TaskRoles::UID] = "uid";
    21. MyModel taskModel;
    22. taskModel.setRoles(taskNames);
    To copy to clipboard, switch view to plain text mode 

    My code seems much shorter and less error prone than yours.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #23
    Join Date
    Nov 2011
    Posts
    26
    Thanks
    6
    Thanked 3 Times in 3 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded Qt Jambi
    Platforms
    Unix/X11 Windows

    Default Re: QML ListModel for interaction with C++

    Hmm .. that's correct - so you mean (and yes of course that seems much easier) using the standardmodel that way is much better -> and for inserting i use insertRow()/appendRow() and Insert QStandardItems to it (using the setData of the StandardItem for specifying the data for the specific role)

    Was that your point for so far? (btw - big thanks for your patience! - i hope i am not too exhausting ^^)

  4. #24
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QML ListModel for interaction with C++

    I had a couple of points. Mainly:
    • no declarative items in the model,
    • no custom classes that do not add anything new to the ecosystem,
    • no need for custom models not doing anything different from what COTS are doing.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Replies: 6
    Last Post: 12th March 2012, 11:06
  2. ListModel.remove() crashes program
    By truefusion in forum Qt Quick
    Replies: 5
    Last Post: 5th February 2012, 16:27
  3. QML and C++ interaction
    By cueMan in forum Qt Programming
    Replies: 3
    Last Post: 11th November 2010, 08:30
  4. UI Interaction gone!
    By zgulser in forum Qt Programming
    Replies: 3
    Last Post: 15th May 2010, 13:08
  5. A simplest ListModel... no example :(
    By tomek in forum Newbie
    Replies: 5
    Last Post: 7th January 2006, 01:32

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.