Set color to tableview to certain row
-
Here I want to show row "GREEN" to row with important false
and "BLUE" to row with important trueIt is fetched from database using mysql query
tb= QSqlDatabase::addDatabase("QMYSQL","full-settings-table"); tb.setDatabaseName("message"); tb.setPort(3306); tb.setHostName("localhost"); tb.setUserName("root"); tb.setPassword(""); QString command = "select * from messages;"; { if(tb.open()){ QSqlQueryModel *model = new QSqlQueryModel(); QSqlQuery *query = new QSqlQuery(tb); query->prepare(command); if(query->exec()){ model->setQuery(*query); ui->data->setModel(model); }else{ // QMessageBox::warning(this,"dataaaaaaa","not\n"+query->lastError().text()); } }else{ //not connected } } QSqlDatabase::removeDatabase("report"); // removing database
I have gone through these
https://forum.qt.io/topic/83984/how-to-set-current-cell-color-in-a-tableview-and-how-to-set-text-centeraligned
https://forum.qt.io/topic/125874/qtableview-set-background-color-to-some-columns/3They all say some kind of different things Like proxy model and delegate.
But I don't know about this topic.So is there simple way to implement this?
-
I am really torn, here there are 2 solutions:
1)class BackgroundBrushDelegate : public QStyledItemDelegate{ Q_OBJECT Q_DISABLE_COPY(BackgroundBrushDelegate) public: explicit BackgroundBrushDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {} BackgroundBrushDelegate(const QBrush& brush, QObject *parent = nullptr) : QStyledItemDelegate(parent) {} protected: void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override { QStyledItemDelegate::initStyleOption(option,index); if(index.siblingAtColumn(3).data().toBool()) option->backgroundBrush = QBrush(Qt::blue); else option->backgroundBrush = QBrush(Qt::green); } };
ui->data->setItemDelegate(new BackgroundBrushDelegate(this));
class BackgroundBrushProxy : public QIdentityProxyModel{ Q_OBJECT Q_DISABLE_COPY(BackgroundBrushProxy) public: explicit BackgroundBrushProxy(QObject *parent = nullptr) : QIdentityProxyModel(parent) {} QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override{ if(role == Qt::BackgroundRole && index.isValid()){ if(index.siblingAtColumn(3).data().toBool()) return QBrush(Qt::blue); return QBrush(Qt::green) } return QIdentityProxyModel::data(index,role); } };
And replace
ui->data->setModel(model);
with:BackgroundBrushProxy *proxy = new BackgroundBrushProxy(this); proxy->setSourceModel(model); ui->data->setModel(proxy);
The decision on which is better, however, is purely philosophical (is it just user representation so use 1 or is a property of the data and 2 should be used?) and both work. The argument to
siblingAtColumn
is what determines what column is looked at, you probably want to handle it with a private variable + getter/setter methods or with an enum in real code to avoid it breaking when you change the code later on
P.S.
In your code example you are likely leaking the model and there is no reason to allocate the query on the heap. It should be:if(tb.open()){ QSqlQueryModel *model = new QSqlQueryModel(this); QSqlQuery query(tb); query.prepare(command); if(query.exec()){ model->setQuery(query); ui->data->setModel(model);
-
Hi,
Implement a custom QIdentityProxyModel and return the color you want for the background role of that column based on the value at the index.
-
@SGaist
I was about to ask this question. I prepared whole question but was still searching for the answer.
I found this one written by @VRonin (Thank you sir)class BackgroundBrushDelegate : public QStyledItemDelegate{ Q_OBJECT Q_PROPERTY(QBrush backgroundBrush READ backgroundBrush WRITE setBackgroundBrush NOTIFY backgroundBrushChanged) Q_DISABLE_COPY(BackgroundBrushDelegate) public: explicit BackgroundBrushDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {} BackgroundBrushDelegate(const QBrush& brush, QObject *parent = nullptr) : QStyledItemDelegate(parent) , m_backgroundBrush(brush) {} const QBrush& backgroundBrush() const { return m_backgroundBrush; } void setBackgroundBrush(const QBrush& brush) { if(m_backgroundBrush==brush) return; m_backgroundBrush=brush; backgroundBrushChanged(m_backgroundBrush); } signals: void backgroundBrushChanged(const QBrush& brush); protected: void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override { QStyledItemDelegate::initStyleOption(option,index); option->backgroundBrush = m_backgroundBrush; } private: QBrush m_backgroundBrush; }
I am using it. But I don't know how it works and other stuffs.
In addition to @mrjj, QIdentityProxyModel is also a solution.
In that question also You mentioned it but I don't know both of these.
After searching about this, I found majority of answers include either https://doc.qt.io/qt-5/qidentityproxymodel.html or Delegate.
I would be happy to get the answer which looks simple. I am not pro at it. I understand the syntax of upper code but I can't visualize it( I don't know what delegate is and what ProxyModel is 😂😂, I just know sth about model ).
Thank You 😊☺
-
Did you already went through the Model View introduction in Qt's documentation ?
-
I am really torn, here there are 2 solutions:
1)class BackgroundBrushDelegate : public QStyledItemDelegate{ Q_OBJECT Q_DISABLE_COPY(BackgroundBrushDelegate) public: explicit BackgroundBrushDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {} BackgroundBrushDelegate(const QBrush& brush, QObject *parent = nullptr) : QStyledItemDelegate(parent) {} protected: void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override { QStyledItemDelegate::initStyleOption(option,index); if(index.siblingAtColumn(3).data().toBool()) option->backgroundBrush = QBrush(Qt::blue); else option->backgroundBrush = QBrush(Qt::green); } };
ui->data->setItemDelegate(new BackgroundBrushDelegate(this));
class BackgroundBrushProxy : public QIdentityProxyModel{ Q_OBJECT Q_DISABLE_COPY(BackgroundBrushProxy) public: explicit BackgroundBrushProxy(QObject *parent = nullptr) : QIdentityProxyModel(parent) {} QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override{ if(role == Qt::BackgroundRole && index.isValid()){ if(index.siblingAtColumn(3).data().toBool()) return QBrush(Qt::blue); return QBrush(Qt::green) } return QIdentityProxyModel::data(index,role); } };
And replace
ui->data->setModel(model);
with:BackgroundBrushProxy *proxy = new BackgroundBrushProxy(this); proxy->setSourceModel(model); ui->data->setModel(proxy);
The decision on which is better, however, is purely philosophical (is it just user representation so use 1 or is a property of the data and 2 should be used?) and both work. The argument to
siblingAtColumn
is what determines what column is looked at, you probably want to handle it with a private variable + getter/setter methods or with an enum in real code to avoid it breaking when you change the code later on
P.S.
In your code example you are likely leaking the model and there is no reason to allocate the query on the heap. It should be:if(tb.open()){ QSqlQueryModel *model = new QSqlQueryModel(this); QSqlQuery query(tb); query.prepare(command); if(query.exec()){ model->setQuery(query); ui->data->setModel(model);