I 'm trying to color the rows of a QTableView which has a QIdentityProxyModel model as it 's model (which has as source model a QSqlQueryModel).

This is the code (compilable):
Qt Code:
  1. from PyQt4 import QtGui, QtCore, QtSql
  2. from PyQt4.QtCore import QModelIndex
  3. from PyQt4.QtGui import *
  4. import sys
  5.  
  6. def main():
  7. app = QtGui.QApplication(sys.argv)
  8. w = MyWindow()
  9. w.show()
  10. sys.exit(app.exec_())
  11.  
  12. class MyWindow(QtGui.QTableView):
  13. def __init__(self, *args):
  14. QtGui.QTableView.__init__(self, *args)
  15.  
  16. # connect to db (if doesn't exist, it's auto-created)
  17. self.db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
  18. self.db.setDatabaseName('test.db')
  19. self.db.open()
  20.  
  21. #create a table in db and add some data
  22. query = QtSql.QSqlQuery()
  23. query.exec_("DROP TABLE IF EXISTS games")
  24. query.exec_("CREATE TABLE games(id INTEGER PRIMARY KEY, hometeam TEXT, visitorteam TEXT) ")
  25. query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('Star', 'Eagles')")
  26. query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('Best team', 'Reds');")
  27. query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('NonWinners', 'Loosers');")
  28. query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('North', 'South');")
  29. query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('East', 'west');")
  30.  
  31. # set the model
  32. model = QtSql.QSqlQueryModel(self)
  33. model.setQuery("SELECT * FROM games")
  34. proxy_model = ExtraRolesProxyModel(self)#QtGui.QStandardItemModel(0, 2)
  35. proxy_model.setSourceModel(model);
  36.  
  37. self.setModel(proxy_model)
  38.  
  39.  
  40. # paint first two rows
  41. #model.setRowsToBeColored([0,3])
  42. rowsToBeColored = []
  43. for i in range(0, 2):
  44. rowsToBeColored.append(i)
  45. #model.setRowsToBeColored(rowsToBeColored)
  46. index = QtCore.QModelIndex(model.index(i, 0))
  47. model.setData(index, QtCore.Qt.red, QtCore.Qt.BackgroundRole)
  48.  
  49.  
  50.  
  51.  
  52. class ExtraRolesProxyModel(QIdentityProxyModel ):
  53. def __init__(self, dbcursor=None):
  54. super(ExtraRolesProxyModel, self).__init__()
  55. #self.m_extraRoles = []
  56. def data(self, index, role):
  57. hashKey = index.row() << 32 | index.column()
  58. tableIter = self.m_extraRoles.constFind(hashKey)
  59. if tableIter==self.m_extraRoles.constEnd:
  60. return QtSql.QSqlQueryModel.data(index,role);
  61. roleIter = tableIter.value().constFind(role)
  62. if roleIter==tableIter.value().constEnd():
  63. return QtSql.QSqlQueryModel.data(index,role);
  64. return roleIter.value()
  65.  
  66. def setData(self, index, value, role=None):
  67. if not index.isValid():
  68. return False
  69. hashKey = index.row() << 32 | index.column()
  70. if value:
  71. self.m_extraRoles[hashKey][role] = value
  72. self.dataChanged.emit(index,index)
  73. return True;
  74. tableIter = self.m_extraRoles.find(hashKey)
  75. if tableIter== self.m_extraRoles.end():
  76. return False
  77. roleIter = tableIter.value().find(role)
  78. if roleIter==tableIter.value().end():
  79. return False
  80. tableIter.value().erase(roleIter)
  81. if tableIter.value().isEmpty():
  82. self.m_extraRoles.erase(tableIter)
  83. self.dataChanged.emit(index, index)
  84. return True
  85.  
  86.  
  87. if __name__ == "__main__":
  88. main()
To copy to clipboard, switch view to plain text mode 

I get error:
"tableIter = self.m_extraRoles.constFind(hashKey)
AttributeError: 'ExtraRolesProxyModel' object has no attribute 'm_extraRoles"

The class ExtraRolesProxyModel is a 'translation' from C++, this is the C+++ code of it:
Qt Code:
  1. #include <QIdentityProxyModel>
  2. class ExtraRolesProxyModel : public QIdentityProxyModel
  3. {
  4. Q_OBJECT
  5. Q_DISABLE_COPY(ExtraRolesProxyModel)
  6. public:
  7. explicit ExtraRolesProxyModel(QObject* parent=Q_NULLPTR)
  8. :QIdentityProxyModel(parent)
  9. {}
  10. virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE{
  11. const qint64 hashKey = (static_cast<qint64>(index.row()) << 32) | static_cast<qint64>(index.column());
  12. auto tableIter = m_extraRoles.constFind(hashKey);
  13. if(tableIter==m_extraRoles.constEnd())
  14. return QIdentityProxyModel::data(index,role);
  15. auto roleIter = tableIter.value().constFind(role);
  16. if(roleIter==tableIter.value().constEnd())
  17. return QIdentityProxyModel::data(index,role);
  18. return roleIter.value();
  19. }
  20. virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE {
  21. if(!index.isValid())
  22. return false;
  23. Q_ASSERT(index.model()==this);
  24. const qint64 hashKey = (static_cast<qint64>(index.row()) << 32) | static_cast<qint64>(index.column());
  25. if(value.isValid()){
  26. m_extraRoles[hashKey][role] = value;
  27. emit dataChanged(index,index,QVector<int>(1,role));
  28. return true;
  29. }
  30. auto tableIter = m_extraRoles.find(hashKey);
  31. if(tableIter==m_extraRoles.end())
  32. return false;
  33. auto roleIter = tableIter.value().find(role);
  34. if(roleIter==tableIter.value().end())
  35. return false;
  36. tableIter.value().erase(roleIter);
  37. if(tableIter.value().isEmpty())
  38. m_extraRoles.erase(tableIter);
  39. emit dataChanged(index,index,QVector<int>(1,role));
  40. return true;
  41. }
  42.  
  43. private:
  44. QHash<qint64,QHash<qint32,QVariant> > m_extraRoles;
  45. };
To copy to clipboard, switch view to plain text mode 

Any ideas are welcome.