Change color of a row of a QSqlQueryModel (QTableView)?
-
@Panoss That was exactly how it works in my application. Maybe they just support the dataChanged signal, which you used earlier. But I just saw, that you do not specify the correct arguments. You have to send the signal like:
dataChanged( ModelIndex to first item changed, ModelIndex to last item changed )
Model indices can be created with:
QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const -
@c64zottel said in Change color of a row of a QSqlQueryModel (QTableView)?:
@Panoss That was exactly how it works in my application.
Maybe you could post the code from your setData function?
And I will 'translate' it in python. -
@Panoss I don't have a setData function. The code I use for reset is:
void BattlefieldModel::refresh( const QSet< LinearCoordinate > & indices ) { for( int lc : indices ) { QModelIndex a = index( lc ); emit dataChanged( a, a ); } }
But this is only ok because, ... well lets not get into it.
The arguments of index ( row, column) is just the position you want to update. Since I have just rows, I update just rows.
-
First of all, let me start by saying that using a
QStandardItemModel
filled manually from aQSqlQuery
is probably the fastest way to go.having said that you can use this proxy model to make it work:
Sorry for C++
#include <QIdentityProxyModel> class ExtraRolesProxyModel : public QIdentityProxyModel { Q_OBJECT Q_DISABLE_COPY(ExtraRolesProxyModel) public: explicit ExtraRolesProxyModel(QObject* parent=Q_NULLPTR) :QIdentityProxyModel(parent) {} virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE{ const qint64 hashKey = (static_cast<qint64>(index.row()) << 32) | static_cast<qint64>(index.column()); auto tableIter = m_extraRoles.constFind(hashKey); if(tableIter==m_extraRoles.constEnd()) return QIdentityProxyModel::data(index,role); auto roleIter = tableIter.value().constFind(role); if(roleIter==tableIter.value().constEnd()) return QIdentityProxyModel::data(index,role); return roleIter.value(); } virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE { if(!index.isValid()) return false; Q_ASSERT(index.model()==this); const qint64 hashKey = (static_cast<qint64>(index.row()) << 32) | static_cast<qint64>(index.column()); if(value.isValid()){ m_extraRoles[hashKey][role] = value; emit dataChanged(index,index,QVector<int>(1,role)); return true; } auto tableIter = m_extraRoles.find(hashKey); if(tableIter==m_extraRoles.end()) return false; auto roleIter = tableIter.value().find(role); if(roleIter==tableIter.value().end()) return false; tableIter.value().erase(roleIter); if(tableIter.value().isEmpty()) m_extraRoles.erase(tableIter); emit dataChanged(index,index,QVector<int>(1,role)); return true; } private: QHash<qint64,QHash<qint32,QVariant> > m_extraRoles; };
-
-
I translated it likes this: (I get no error on this line, seems ok)
hashKey = index.row() << 32 | index.column()
But this one;
auto tableIter = m_extraRoles.constFind(hashKey);
Converted to python:
tableIter = m_extraRoles.constFind(hashKey)
Says variable m_extraRoles 'Unresolved reference'. It has not been declared anywhere.
-
Yes, you 're right VRonin:
tableIter = self.m_extraRoles.constFind(hashKey)
This shows no underlined code in Pychrm (if there were any errors, it would be underlined. With red color.)
But this look very hard to convert to python:
Q_ASSERT(index.model()==this)
Q_ASSERT?? omg
-
-
And this is the whole code (of the class):
class ExtraRolesProxyModel(QIdentityProxyModel ): def __init__(self, dbcursor=None): super(ExtraRolesProxyModel, self).__init__() def data(self, index, role): hashKey = index.row() << 32 | index.column() tableIter = self.m_extraRoles.constFind(hashKey) if tableIter==self.m_extraRoles.constEnd: return QtSql.QSqlQueryModel.data(index,role); roleIter = tableIter.value().constFind(role) if roleIter==tableIter.value().constEnd(): return QtSql.QSqlQueryModel.data(index,role); return roleIter.value() def setData(self, index, value, role=None): if not index.isValid(): return False hashKey = index.row() << 32 | index.column() if value: self.m_extraRoles[hashKey][role] = value self.dataChanged.emit(index,index) return True; tableIter = self.m_extraRoles.find(hashKey) if tableIter== self.m_extraRoles.end(): return False roleIter = tableIter.value().find(role) if roleIter==tableIter.value().end(): return False tableIter.value().erase(roleIter) if tableIter.value().isEmpty(): self.m_extraRoles.erase(tableIter) self.dataChanged.emit(index, index) return True
-
@Panoss said in Change color of a row of a QSqlQueryModel (QTableView)?:
AttributeError: 'ExtraRolesProxyModel' object has no attribute 'm_extraRoles'
You have to declare it in the
__init__
method (not sure how you deal with templates in python though)
@Panoss said in Change color of a row of a QSqlQueryModel (QTableView)?:
if tableIter==self.m_extraRoles.constEnd:
Missing ()
if value:
Does it work?
-
I made the suggested corrections:
if tableIter==self.m_extraRoles.constEnd():
And:
if value.isValid():
But I don't knw how to declare the m_extraRoles, so I declared it as list, which obviously, is incorrect.
class ExtraRolesProxyModel(QIdentityProxyModel ): def __init__(self, dbcursor=None): super(ExtraRolesProxyModel, self).__init__() self.m_extraRoles = []
(the '= []' means 'define it as list' )
-
you probably have to use a dict. Let's try this:
I do not know python so consider this just a guideline
class ExtraRolesProxyModel(QIdentityProxyModel ): def __init__(self, dbcursor=None): super(ExtraRolesProxyModel, self).__init__() self.m_extraRoles=dict() def data(self, index, role): hashKey = QByteArray() keyStream = QDataStream(hashKey,QIODevice::WriteOnly) keyStream.writeInt32(index.row()) keyStream.writeInt32(index.column()) keyStream.writeInt32(role) if self.m_extraRoles.has_key(hashKey): return self.m_extraRoles[hashKey] return QtSql.QSqlQueryModel.data(index,role) def setData(self, index, value, role=None): if not index.isValid(): return False hashKey = QByteArray() keyStream = QDataStream(hashKey,QIODevice::WriteOnly) keyStream.writeInt32(index.row()) keyStream.writeInt32(index.column()) keyStream.writeInt32(role) if value.isValid(): self.m_extraRoles[hashKey]=value self.dataChanged.emit(index,index) return True if self.m_extraRoles.has_key(hashKey): del self.m_extraRoles[hashKey] self.dataChanged.emit(index,index) return True return False