View Full Version : Color the rows in QTableView
grub87
17th June 2009, 15:41
Hi! I'm using a QTableView and want to color the background of the rows, but i can't figure out how. THANKS FOR YOUR HELP!!
spirit
17th June 2009, 15:55
take a look at Qt::BackgroundRole, i.e. you need to set data for a needed item,
you can do it (in general way) as:
...
QModelIndex index = model->index(0, 0);
model->setData(index, Qt::red, Qt::BackgroundRole);
...
estanisgeyer
17th June 2009, 15:57
Hi, subclass the your Model (QSqlQuery for example) and reimplement virtual method data, like this:
QVariant MyModelSqlQryModel::data(const QModelIndex &idx, int role) const
{
QVariant v = QSqlQueryModel::data(idx, role);
if (role == Qt::BackgroundColor)
{
return QVariant(QColor(Qt::yellow));
}
return (v);
}
Marcelo E. Geyer
spirit
17th June 2009, 16:06
here is a compilable example
#include <QtGui>
#include <QApplication>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QTableWidget table(10, 10);
QAbstractItemModel *model = table.model();
for (int row = 0; row < table.rowCount(); ++row) {
for (int column = 0; column < table.columnCount(); ++column) {
QTableWidgetItem *newItem = new QTableWidgetItem(QObject::tr("%1").arg((row+1)*(column+1)));
table.setItem(row, column, newItem);
const QModelIndex index = model->index(row, column);
model->setData(index, QColor(qrand()%255, qrand()%255, qrand()%255), Qt::BackgroundRole);
}
}
table.show();
return app.exec();
}
grub87
17th June 2009, 16:07
Hi!! I try to put your code in a cycle, so it will color all the tableView, but it didn't work:
int row = 0;
if (query.isActive())
while(query.next()){
QModelIndex index = model->index(row, 1);
model->setData(index, Qt::red, Qt::BackgroundRole);
row++;
}
spirit
17th June 2009, 16:31
if you use some of QSql*Model then you should approach which estanisgeyer suggested of write your own delegate.
an exmaple
class ColorDelegate: public QItemDelegate
{
public:
ColorDelegate(QObject *parent = 0) : QItemDelegate(parent) {}
public:
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
drawBackground(painter, option, index);
QItemDelegate::paint(painter, option, index);
}
protected:
virtual void drawBackground(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index);
painter->fillRect(option.rect, QColor(qrand()%255, qrand()%255, qrand()%255));
}
};
applying a delegate for a table
...
table->setItemDelegate(new ColorDelegate(table));
...
but in this case when a table is being resized items colors is being changed to.
grub87
17th June 2009, 16:59
Excelent!! thanks!! that get me out of trouble, and i'm also changing the colors of rows like this:
ui.latabladiario->setItemDelegateForRow(0, new ColorDelegate(ui.latabladiario));
ui.latabladiario->setItemDelegateForRow(3, new ColorDelegate(ui.latabladiario));
spirit
17th June 2009, 17:09
add a map or hash to your delegate for keeping color by id (or even better add a proper method in a delegate in which you can pass this map/hash). then you have an index (QModelIndex) using it you can get your id from a table, this should look like this
class ColorDelegate: public QItemDelegate
{
public:
ColorDelegate(QObject *parent = 0) : QItemDelegate(parent) {}
public:
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
drawBackground(painter, option, index);
QItemDelegate::paint(painter, option, index);
}
void setColorMap(const QMap<int, QColor> &colorMap) { m_colorMap = colorMap; }
protected:
virtual void drawBackground(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.column() == 1) {//assume that id keeps in a second column
const int id = index.data().toInt();
painter->fillRect(option.rect, m_colorMap.value(id));
}
}
private:
QMap<int, QColor> m_colorMap;
};
usage
...
ColorDelegate *delegate = new ColorDelegate(&table);
QMap<int, QColor> map;
for (int i = 0; i < 100; ++i)
map.insert(i, QColor(qrand()%255, qrand()%255, qrand()%255));
delegate->setColorMap(map);
table->setItemDelegate(delegate);
...
spirit
17th June 2009, 17:10
Excelent!! thanks!! that get me out of trouble, and i'm also changing the colors of rows like this:
ui.latabladiario->setItemDelegateForRow(0, new ColorDelegate(ui.latabladiario));
ui.latabladiario->setItemDelegateForRow(3, new ColorDelegate(ui.latabladiario));
yup, or like this :)
estanisgeyer
17th June 2009, 17:13
There are several ways to do this, see the example below, if the date is less than the current, applying background color of red.
Example:
QVariant MyModel::data(const QModelIndex &idx, int role) const
{
QVariant v = QSqlQueryModel::data(idx, role);
if ((role == Qt::BackgroundRole) &&
(index(idx.row(), 0, idx.parent()).data().toDate() < QDate::currentDate()))
{
return QVariant(QColor(255, 0, 0));
}
return (v);
}
Marcelo E. Geyer
grub87
17th June 2009, 18:06
This is my final code, i only put in a for cycle to move along the rows:
int polizaInicial = 1;
for (int row = 0; row < numRows; row++) {
const QModelIndex index = model->index(row, 1);
if(index.data().toInt() == polizaInicial){
ui.latabladiario->setItemDelegateForRow(row, new ColorDelegate(ui.latabladiario));
}
else{
polizaInicial++;
}
THANKS!!
You can also use style sheets for selection:
http://doc.trolltech.com/4.5/stylesheet-examples.html#customizing-qtableview
I think background color and color should work as well, but that needs to be tested.
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.