Results 1 to 1 of 1

Thread: having trouble populating a multi-column TableView from C++ model

  1. #1
    Join Date
    Jun 2015
    Posts
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: having trouble populating a multi-column TableView from C++ model

    I've been trying to populate a tableview with dynamically created columns based on model headers (this works as intended now!) However I still can't seem to get the TableView to correctly read my model data. I checked to see if EmployeeTableModel::data() was ever called and it wasn't so thats a pretty big red flag.

    My compiler errors are ReferenceError: score is not defined, etc for all user created roles. My EmployeeModelMaster works perfectly even though it has essentially the same class structure.

    I think I'm missing something simple, the qml file will be attached below.

    main.cpp
    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3. QApplication app(argc, argv);
    4. QQmlApplicationEngine engine;
    5.  
    6. EmployeeModelMaster* masterModel = new EmployeeModelMaster();
    7.  
    8. EmployeeModelTable* table = new EmployeeModelTable();
    9. QObject::connect(masterModel, SIGNAL(updateMirrors(int,EmployeeModelMaster*)), table, SLOT(masterDataChanged(int,EmployeeModelMaster*)));
    10. masterModel->configSQL();
    11. qDebug()<<"info successfully pulled from database? " << masterModel->pullFromSQL();
    12.  
    13.  
    14. engine.rootContext()->setContextProperty("baseTableModel", table);
    15. engine.rootContext()->setContextProperty("headers", table->headerList());
    16.  
    17. qDebug()<<"right before loading shyftwrk.qml";
    18.  
    19. engine.load(QUrl(QStringLiteral("qrc:///qml/ShyftWrk.qml")));
    20. qDebug()<<"engine loaded shyftwrk.qml";
    21.  
    22.  
    23.  
    24. return app.exec();
    25. }
    To copy to clipboard, switch view to plain text mode 

    table.h
    Qt Code:
    1. #ifndef EMPLOYEEMODELTABLE_H
    2. #define EMPLOYEEMODELTABLE_H
    3.  
    4. class EmployeeModelTable : public QAbstractTableModel
    5. /* this model is a mirror of EmployeeModelMaster, it is not intended to have data directly set; to update this table
    6.   * please connect the masterChanged() slot. */
    7. {
    8.  
    9. Q_OBJECT
    10. Q_PROPERTY(QStringList headerList READ headerList)
    11.  
    12. public:
    13.  
    14. typedef QList<QList<EmployeeData*> >::const_iterator const_iterator; //does this do anything?
    15.  
    16.  
    17. explicit EmployeeModelTable(QObject *parent=0);
    18.  
    19.  
    20. public:
    21.  
    22. enum EmployeeModelTableDataRole
    23. {
    24. nameRole=Qt::UserRole+1,
    25. positionRole,
    26. portraitRole,
    27. scoreRole
    28. };
    29.  
    30. public: //virtual inherited members from QAbstractTableModel
    31.  
    32. int rowCount(const QModelIndex &parent = QModelIndex()) const;
    33.  
    34. int columnCount(const QModelIndex &parent = QModelIndex()) const;
    35.  
    36. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    37.  
    38. QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    39.  
    40. bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::DisplayRole);
    41.  
    42. Qt::ItemFlags flags(const QModelIndex &index) const;
    43.  
    44.  
    45. public: //new members specifically for our implementation
    46.  
    47. bool newHeader(const QVariant &value);
    48.  
    49. QString name() const;
    50.  
    51. QStringList headerList();
    52.  
    53. const_iterator begin()const{return m_data.begin();}
    54.  
    55. const_iterator end()const{return m_data.end();}
    56.  
    57. signals:
    58.  
    59. void headerDataChanged(int first, int last); //the only important signal from the tableModel
    60.  
    61. void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
    62. public slots:
    63.  
    64. void masterDataChanged(int rows, EmployeeModelMaster* master); //tells employeeModelTable to update, pulls from employeeModelMaster.
    65.  
    66.  
    67. protected:
    68.  
    69. QHash<int, QByteArray> roleNames() const;
    70.  
    71. QList < EmployeeData* > str_data;
    72.  
    73. QMap < int, QString > m_headerData;
    74.  
    75. public:
    76.  
    77. QList < QList < EmployeeData* > > m_data;
    78.  
    79. int headerItr;
    80.  
    81. };
    82.  
    83. #endif // EMPLOYEEMODELTABLE_H
    To copy to clipboard, switch view to plain text mode 

    table.cpp
    Qt Code:
    1. EmployeeModelTable::EmployeeModelTable(QObject *parent)
    2. {
    3. QList<EmployeeData*> null;
    4. m_data.append(null);
    5. headerItr =0;
    6. }
    7.  
    8. int EmployeeModelTable::rowCount(const QModelIndex &parent) const
    9. {
    10. Q_UNUSED(parent);
    11. if(m_data[0].isEmpty())
    12. return 0;
    13. return m_data[0].count(); // since each column is identical, get the count from column 0
    14. }
    15.  
    16. int EmployeeModelTable::columnCount(const QModelIndex &parent) const //all columns are identical
    17. {
    18. Q_UNUSED(parent);
    19.  
    20. return m_data.count();
    21.  
    22. }
    23.  
    24. QVariant EmployeeModelTable::data(const QModelIndex &index, int role) const
    25. {
    26. if(!index.isValid())
    27. return QVariant();
    28. if(index.row() <0 || index.row()>= this->rowCount(index))
    29. return QVariant();
    30.  
    31. if(index.column() <0 || index.column()>= this->columnCount())
    32. return QVariant();
    33.  
    34. const EmployeeData *data = m_data[index.column()][index.row()];
    35.  
    36. if (role == nameRole)
    37. return data->name();
    38.  
    39. else if (role == portraitRole)
    40. return data->portrait();
    41.  
    42. else if(role == positionRole)
    43. return data->position();
    44.  
    45. else if(role == scoreRole)
    46. return data->score();
    47.  
    48. else
    49. return QVariant();
    50. }
    51.  
    52. bool EmployeeModelTable::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
    53. {
    54. Q_UNUSED(orientation); //orientation will always be horizontal
    55.  
    56. if(role != Qt::DisplayRole)
    57. return false;
    58.  
    59. for(int i=0; i <= m_headerData.count(); i++) //if the header already exists, don't make another one
    60. {
    61. if(m_headerData.value(i) == value)
    62. return false;
    63. }
    64.  
    65. m_headerData[section] = value.toString();
    66. headerDataChanged(section, m_headerData.size());
    67. return true;
    68. }
    69.  
    70. bool EmployeeModelTable::newHeader(const QVariant &value)
    71. {
    72.  
    73. for(int i=0; i<m_headerData.size(); i++) //if the header already exists, don't make another one
    74. {
    75.  
    76. if(!m_headerData.isEmpty())
    77. {
    78. if(m_headerData[i] == value.toString())
    79. {
    80. return false;
    81. }
    82. }
    83. }
    84. beginInsertColumns(QModelIndex(), this->columnCount(), this->columnCount()+1);
    85. m_headerData[headerItr] = value.toString();
    86. m_data.append(str_data);
    87. endInsertColumns();
    88. headerItr++;
    89. return true;
    90. }
    91.  
    92. QVariant EmployeeModelTable::headerData(int section, Qt::Orientation orientation, int role) const
    93. {
    94. Q_UNUSED(orientation); //orientation will always be horizontal
    95. if(role != Qt::DisplayRole)
    96. return QVariant();
    97. return m_headerData.value(section);
    98. }
    99.  
    100.  
    101. Qt::ItemFlags EmployeeModelTable::flags(const QModelIndex &index) const
    102. {
    103. if(index.isValid())
    104. return QAbstractTableModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    105.  
    106. return Qt::NoItemFlags;
    107. }
    108.  
    109.  
    110. QHash<int, QByteArray> EmployeeModelTable::roleNames() const
    111. {
    112. QHash<int, QByteArray> roles;
    113. roles[nameRole] = "name";
    114. roles[portraitRole] = "portrait";
    115. roles[positionRole] = "position";
    116. roles[scoreRole] = "score";
    117. return roles;
    118. }
    119.  
    120. void EmployeeModelTable::masterDataChanged(int rows, EmployeeModelMaster* master)
    121. {
    122. for(int k=0; k < this->columnCount(); k++)
    123. {
    124. while(rows > this->m_data[k].count()) // if the new row is bigger than the current, append with dummies
    125. {
    126. beginInsertRows(QModelIndex(), rowCount(), rowCount()+1);
    127. EmployeeData* nullperson = new EmployeeData();
    128. this->m_data[k].append(nullperson);
    129. this->str_data.append(nullperson);
    130. endInsertRows();
    131. }
    132. for(int i=0; i < rows; i++)
    133. {
    134. if(i > m_data[k].count())
    135. {
    136. beginInsertRows(QModelIndex(), rowCount(), rowCount()+1);
    137. this->m_data[k].append(master->m_data[i]);
    138. endInsertRows();
    139. }
    140. if(i > str_data.count())
    141. {
    142. this->str_data.append(master->m_data[i]);
    143. }
    144. beginInsertRows(QModelIndex(), 0, rowCount());
    145. this->m_data[k][i] = master->m_data[i]; //replace existing data in table with new data from master
    146. endInsertRows();
    147. this->str_data[i] = master->m_data[i];
    148. newHeader(this->m_data[k][i]->position());
    149. }
    150. }
    151. }
    152.  
    153. QStringList EmployeeModelTable::headerList()
    154. {
    155. return m_headerData.values();
    156. }
    To copy to clipboard, switch view to plain text mode 

    qml snippet
    Qt Code:
    1. import QtQuick 2.0
    2. import QtQuick.Controls 1.2
    3. Rectangle{
    4. id: root
    5. radius: 5
    6. TableView{
    7. id: schedulerTableView
    8. itemDelegate: tableDelegate
    9. resources:
    10. {
    11. var headerData = headers
    12. var temp = []
    13. for(var i=0; i<headerData.length; i++)
    14. {
    15. var role = headerData[i]
    16. temp.push(columnComponent.createObject(schedulerTableView, { "role": role, "title": role}))
    17. console.log("column #" + i + " is named : " + role);
    18. }
    19. return temp
    20. }
    21. model: baseTableModel
    22. anchors.fill: root
    23.  
    24. }
    25.  
    26. Component
    27. {
    28. id: columnComponent
    29. TableViewColumn{width: 220 }
    30. }
    31.  
    32.  
    33. Component{
    34. id: tableDelegate
    35. Rectangle{
    36. id: delRectangle
    37. height: 250
    38. z:0
    39. Clickable{
    40. id: portraitText
    41. source: portrait
    42. smooth: true
    43. antialiasing: true
    44. anchors.top: parent.top
    45. anchors.horizontalCenter: parent.horizontalCenter
    46. height: 150
    47. fillMode: Image.PreserveAspectFit
    48. overlayOpacity: 0.4
    49. }
    50. Text{
    51. id: nameText
    52. text: name
    53. anchors.horizontalCenter: parent.horizontalCenter
    54. anchors.top: portraitText.bottom
    55. }
    56. Text{
    57. id: positionText
    58. anchors.top: nameText.bottom
    59. anchors.horizontalCenter: parent.horizontalCenter
    60. text: position
    61. }
    62. Text{
    63. id:scoreText
    64. anchors.top: positionText.bottom
    65. anchors.horizontalCenter: parent.horizontalCenter
    66. text: score
    67. }
    68. }
    69.  
    70. }
    71.  
    72. }
    To copy to clipboard, switch view to plain text mode 


    Added after 21 minutes:


    also I should mention, if I convert my TableView to a ListView, it populates with the first column from the model as intended, which makes me think I'm very close.


    Added after 18 minutes:


    I figured it out: If add the prefix "model." to each of my itemDelegate sources (image src, text text, etc) then it is read correctly. Not entirely sure why that's the case but I'm happy I figured it out.
    Last edited by zeryx; 12th June 2015 at 20:19.

Similar Threads

  1. Autoscroll TableView when Dragging Column
    By stefanadelbert in forum Qt Programming
    Replies: 3
    Last Post: 13th November 2012, 18:43
  2. Replies: 0
    Last Post: 18th April 2011, 16:07
  3. Tableview - Three subcolumns inside one column?
    By qlands in forum Qt Programming
    Replies: 2
    Last Post: 24th March 2010, 16:04
  4. QTableView column trouble
    By nategoofs in forum Qt Programming
    Replies: 6
    Last Post: 27th October 2009, 21:14
  5. Can a QListView support multi-column?
    By wesley in forum Qt Programming
    Replies: 3
    Last Post: 7th March 2008, 09:00

Tags for this Thread

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.