Change color of a row of a QTableView? - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: Change color of a row of a QTableView? (/thread-3453.html) |
Change color of a row of a QTableView? - panoss - May-24-2017 How can I change the color of a row of QTableView which has as model a QStandardItemModel? I tried this with no success: index = self.games_model.index(0, 0) model.setData(index, QtCore.Qt.red, QtCore.Qt.BackgroundRole) model.emit(QtCore.SIGNAL('dataChanged(QModelIndex)'), index) RE: Change color of a row of a QTableView? - panoss - May-25-2017 I changed the 'QtCore.Qt.red' to 'QBrush(Qt.red)' and works! Here is a small working example: from PyQt4 import QtGui, QtCore from PyQt4.QtCore import * from PyQt4.QtGui import * import sys def main(): app = QApplication(sys.argv) w = MyWindow() w.show() sys.exit(app.exec_()) class MyWindow(QTableView): def __init__(self, *args): QTableView.__init__(self, *args) model = QtGui.QStandardItemModel(0, 2) self.setModel(model) for i in range(0,6): newRow = model.rowCount(); model.insertRow(newRow); # paint first two rows for i in range(0, 2): model.setData(model.index(i, 0), QBrush(Qt.red), QtCore.Qt.BackgroundRole) model.setData(model.index(i, 1), QBrush(Qt.red), QtCore.Qt.BackgroundRole) if __name__ == "__main__": main()But I do have a question: when I comment out the line 'from PyQt4.QtCore import *', I get an error 'Qt unresolved reference' even though I have the line 'from PyQt4 import QtGui, QtCore'. So, what is the proper way to import QtCore without having to import it twice? RE: Change color of a row of a QTableView? - snippsat - May-25-2017 It's good to get rid of import * .It's annoying that many think that * is okay when using a GUI framework,it's really not So have to add QtGui, QtCore to all plasses * has taken it away.Don't like to see main first in code. from PyQt4 import QtGui, QtCore import sys class MyWindow(QtGui.QTableView): def __init__(self, *args): QtGui.QTableView.__init__(self, *args) model = QtGui.QStandardItemModel(0, 2) self.setModel(model) for i in range(0, 6): newRow = model.rowCount() model.insertRow(newRow) # paint first two rows for i in range(0, 2): model.setData(model.index(i, 0), QtGui.QBrush( QtCore.Qt.red), QtCore.Qt.BackgroundRole) model.setData(model.index(i, 1), QtGui.QBrush( QtCore.Qt.red), QtCore.Qt.BackgroundRole) def main(): app = QtGui.QApplication(sys.argv) w = MyWindow() w.show() sys.exit(app.exec_()) if __name__ == "__main__": main() RE: Change color of a row of a QTableView? - panoss - May-29-2017 I 'm trying to do the same with QSqlQueryModel but it doesn't work! Here is a compilable code sample: import sys from PyQt4 import QtGui, QtCore, QtSql def main(): app = QtGui.QApplication(sys.argv) w = MyWindow() w.show() sys.exit(app.exec_()) class MyWindow(QtGui.QTableView): def __init__(self, *args): QtGui.QTableView.__init__(self, *args) # connect to db (if doesn't exist, it's auto-created) self.db = QtSql.QSqlDatabase.addDatabase('QSQLITE') self.db.setDatabaseName('test.db') self.db.open() #create a table in db and add some data query = QtSql.QSqlQuery() query.exec_("DROP TABLE IF EXISTS games") query.exec_("CREATE TABLE games(id INTEGER PRIMARY KEY, hometeam TEXT, visitorteam TEXT) ") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('Star', 'Eagles')") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('Best team', 'Reds');") # set the model model = QtSql.QSqlQueryModel(self)#QtGui.QStandardItemModel(0, 2) self.setModel(model) model.setQuery("SELECT * FROM games") # paint first two rows for i in range(0, 2): model.setData(model.index(i, 0), QtGui.QBrush(QtCore.Qt.red), QtCore.Qt.BackgroundRole) model.setData(model.index(i, 1), QtGui.QBrush(QtCore.Qt.red), QtCore.Qt.BackgroundRole) if __name__ == "__main__": main()What could be the problem? RE: Change color of a row of a QTableView? - panoss - May-29-2017 I subclassed it: class ColorfullSqlQueryModel(QtSql.QSqlQueryModel): def __init__(self, dbcursor=None): super(ColorfullSqlQueryModel, self).__init__() def data(self, QModelIndex, role=None): v = QtSql.QSqlQueryModel.data(self, QModelIndex, role); if role == QtCore.Qt.BackgroundRole: return QtGui.QColor(QtCore.Qt.yellow) return (v);It works!! Turns all rows to yellow! But how can I make it paint only the rows I want? How can I pass the color to function data? RE: Change color of a row of a QTableView? - panoss - May-30-2017 Finally, I ended in a, relatively, good solution: from PyQt4 import QtGui, QtCore, QtSql #from PyQt4.QtCore import * from PyQt4.QtGui import * import sys def main(): app = QtGui.QApplication(sys.argv) w = MyWindow() w.show() sys.exit(app.exec_()) class MyWindow(QtGui.QTableView): def __init__(self, *args): QtGui.QTableView.__init__(self, *args) # connect to db (if doesn't exist, it's auto-created) self.db = QtSql.QSqlDatabase.addDatabase('QSQLITE') self.db.setDatabaseName('test.db') self.db.open() #create a table in db and add some data query = QtSql.QSqlQuery() query.exec_("DROP TABLE IF EXISTS games") query.exec_("CREATE TABLE games(id INTEGER PRIMARY KEY, hometeam TEXT, visitorteam TEXT) ") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('Star', 'Eagles')") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('Best team', 'Reds');") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('NonWinners', 'Loosers');") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('North', 'South');") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('East', 'west');") # set the model model = ColorfullSqlQueryModel(self)#QtGui.QStandardItemModel(0, 2) self.setModel(model) model.setQuery("SELECT * FROM games") # paint first two rows model.setRowsToBeColored([0,3]) for i in range(0, 2): index = QtCore.QModelIndex(model.index(i, 0)) model.setData(index, QtCore.Qt.red, QtCore.Qt.BackgroundRole) class ColorfullSqlQueryModel(QtSql.QSqlQueryModel): def __init__(self, dbcursor=None): super(ColorfullSqlQueryModel, self).__init__() def setRowsToBeColored(self, rows): self.rows = rows def data(self, index, role): row = index.row() print("row=", row, " row in self.rows=", row in self.rows) if role == QtCore.Qt.BackgroundRole and row in self.rows: return QBrush(QtCore.Qt.red) return QtSql.QSqlQueryModel.data(self, index, role); if __name__ == "__main__": main() RE: Change color of a row of a QTableView? - panoss - Jun-07-2017 I 'm trying to 'translate' c++ to python. With some help from qt forum, I got to this (it's compilable): from PyQt4 import QtGui, QtCore, QtSql from PyQt4.QtCore import QModelIndex, QByteArray, QDataStream, QIODevice from PyQt4.QtGui import * import sys QString = type("") from past.builtins import unicode def main(): app = QtGui.QApplication(sys.argv) w = MyWindow() w.show() sys.exit(app.exec_()) class MyWindow(QtGui.QTableView): def __init__(self, *args): QtGui.QTableView.__init__(self, *args) # connect to db (if doesn't exist, it's auto-created) self.db = QtSql.QSqlDatabase.addDatabase('QSQLITE') self.db.setDatabaseName('test.db') self.db.open() #create a table in db and add some data query = QtSql.QSqlQuery() query.exec_("DROP TABLE IF EXISTS games") query.exec_("CREATE TABLE games(id INTEGER PRIMARY KEY, hometeam TEXT, visitorteam TEXT) ") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('Star', 'Eagles')") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('Best team', 'Reds');") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('NonWinners', 'Loosers');") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('North', 'South');") query.exec("INSERT INTO games (hometeam, visitorteam) VALUES ('East', 'west');") # set the model model = QtSql.QSqlQueryModel(self) model.setQuery("SELECT * FROM games") # paint first two rows for i in range(0, 2): index = QtCore.QModelIndex(model.index(i, 0)) model.setData(index, QtCore.Qt.red, QtCore.Qt.BackgroundRole) # create the proxy model proxy_model = ExtraRolesProxyModel(self) # QtGui.QStandardItemModel(0, 2) # set the proxy 's source proxy_model.setSourceModel(model) # set the proxy as TableView 's source self.setModel(proxy_model) class ExtraRolesProxyModel(QIdentityProxyModel): def __init__(self, dbcursor=None): super(ExtraRolesProxyModel, self).__init__() self.m_extraRoles = dict() def data(self, index, role): if role == QtCore.Qt.BackgroundRole: role_str = "BackgroundRole" if role == QtCore.Qt.DisplayRole: role_str = "DisplayRole" print("ExtraRolesProxyModel data was called row=", index.row(), " role=", 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): if hashKey in self.m_extraRoles: hashKey = unicode([QString(u'hashKey')]) return self.m_extraRoles[hashKey] return QIdentityProxyModel.data(self, index, role) def setData(self, index, value, role=None): print("ExtraRolesProxyModel setData was called=") if not index.isValid(): return False hashKey = QByteArray() keyStream = QDataStream(hashKey, QIODevice.WriteOnly) keyStream.writeInt32(index.row()) keyStream.writeInt32(index.column()) keyStream.writeInt32(role) print("value=", value) if value.isValid(): self.m_extraRoles[hashKey] = value self.dataChanged.emit(index, index) return True #if self.m_extraRoles.has_key(hashKey): if hashKey not in self.m_extraRoles: del self.m_extraRoles[hashKey] self.dataChanged.emit(index, index) return True return False if __name__ == "__main__": main()The original c++ code for the class ExtraRolesProxyModel is this: 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; };Well, python code does not make colored rows. Can you spot any problems in the 'tranlsation'? RE: Change color of a row of a QTableView? - Mafireyi - Sep-23-2017 Hi Panoss, I saw your post about colouring some rows in your qsqltablemodel. I have managed to colour some my rows using the data() mathod and make them uneditable with the flag method. Before I did this my model was editable and could automatically update my table. However soon as i color some columns, it my edits just disappear soon as I move to next Field. Have u came across this problem before and if so, how did u get around it. Thanks |