I used QTableView with QAbstractItemModel. I started with a table with only one row which has a "Add" button (I added it by setIndexWidget)
When clicking this button I add a new blank row. If the new row is inserted below it's fine, however if inserted above then the "Add" button in the old row disappears. However I wanted to insert above so the row with the "add" button is always at the bottom. Appreciate any input.

The calls I reimplemented:

Qt Code:
  1. QVariant VarTableModel::data(const QModelIndex & index, int role) const
  2. {
  3. QVariant var;
  4.  
  5. if(index.isValid())
  6. {
  7.  
  8. if(role == Qt::DisplayRole)
  9. {
  10. // the last row is just the "Add" button, no data
  11. if((index.column() == 2) && (index.row() != rowCount()-1))
  12. {
  13. int idx = getDesignVarIndexFromRow(index.row());
  14. if(idx >= 0)
  15. {
  16. Variable desVar = designVariables.at(idx);
  17. QString exp;
  18. createVarExpFromStruct(desVar, exp);
  19. var.setValue(exp);
  20. }
  21. }
  22. }
  23. else if(role == Qt::CheckStateRole)
  24. {
  25. if((index.column() == 1) && (index.row() != rowCount()-1))
  26. {
  27. enum Qt::CheckState flags;
  28.  
  29. int idx = getDesignVarIndexFromRow(index.row());
  30. if(idx >= 0)
  31. {
  32. Variable desVar = designVariables.at(idx);
  33. if(desVar.enabled)
  34. {
  35. flags = Qt::Checked;
  36. }
  37. else
  38. {
  39. flags = Qt::Unchecked;
  40. }
  41. }
  42. else
  43. {
  44. flags = Qt::Checked;
  45. }
  46. return flags;
  47. }
  48. }
  49. }
  50. return var;
  51. }
  52.  
  53. //----------------------------------------------------------------------------
  54. bool VarTableModel::setData(const QModelIndex& index, const QVariant& value, int role)
  55. {
  56. if(role == Qt::CheckStateRole)
  57. {
  58. int idx = getDesignVarIndexFromRow(index.row());
  59. if(idx >= 0)
  60. {
  61. Variable desVar = designVariables.at(idx);
  62.  
  63. if(value == Qt::Checked)
  64. {
  65. desVar.enabled = true;
  66. }
  67. else
  68. {
  69. desVar.enabled = false;
  70. }
  71. }
  72. }
  73. emit dataChanged(index, index);
  74. return true;
  75. }
  76.  
  77.  
  78. Qt::ItemFlags VarTableModel::flags ( const QModelIndex & index ) const
  79. {
  80. if(index.column() == 1)
  81. {
  82. if(index.row() != rowCount()-1)
  83. {
  84. return Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
  85. }
  86. else // last row with "Add" button
  87. {
  88. return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
  89. }
  90. }
  91. else
  92. {
  93. return QAbstractItemModel::flags(index);
  94. }
  95. }
  96.  
  97. //----------------------------------------------------------------------------
  98. bool VarTableModel::insertRow(int row, const QModelIndex & parent)
  99. {
  100. beginInsertRows(QModelIndex(), row, row);
  101. endInsertRows();
  102. return true;
  103. }
To copy to clipboard, switch view to plain text mode