I have got a QTableView component displaying several types of data in the rows. What I need is to display each type of row by different color. My stylesheet looks like this:
RecordSheet::item {
border: 0px;
color: black;
padding: 1px 0px 0px 3px;
}
RecordSheet::item:selected, RecordSheet::item:selected:!active {
background-color: #e8b417;
color: black;
}
I have two ideas how to achieve this:
Use data()
method in the model and respond to the Qt::BackgroundColorRole
. Unfortunately when I do it, the background color is ignored until I remove the border: 0px;
from the stylesheet and when I remove the border, the styleshhet's padding is ignored. Strange...
Setup a CSS/QSS class for each type of row and set their colors in the stylesheet. Then use the model to assign a proper class for each type of row. So the stylesheet would look like this:
RecordSheet::item {
border: 0px;
color: black;
padding: 1px 0px 0px 3px;
}
RecordSheet::item[class=green_row] {
background-color: green;
}
RecordSheet::item[class=red_row] {
background-color: red;
}
I like this approach more because it separates content from the appearance, but I don't have any idea how to do it. Maybe using an ItemDelegate?
Please, does anybody know a nice and simple solution?
Kind regards and many thanks.
Jan
You don't need stylesheet to do this, styleshhet is not so powerful to do all things that developer wants. Use more powerful thing - delegate. I will show you main idea and working example. Header:
#ifndef ITEMDELEGATEPAINT_H
#define ITEMDELEGATEPAINT_H
#include <QStyledItemDelegate>
class ItemDelegatePaint : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit ItemDelegatePaint(QObject *parent = 0);
ItemDelegatePaint(const QString &txt, QObject *parent = 0);
protected:
void paint( QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index ) const;
QSize sizeHint( const QStyleOptionViewItem &option,
const QModelIndex &index ) const;
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget * editor, const QModelIndex & index) const;
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const;
signals:
public slots:
};
#endif // ITEMDELEGATEPAINT_H
There are many methods here but I will show you only paint, because it is the most important thing for you. Description about another methods you can find in web
cpp:
void ItemDelegatePaint::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QString txt = index.model()->data( index, Qt::DisplayRole ).toString();
if(index.row() == 0)//green row
painter->fillRect(option.rect,QColor(0,255,0));
else
if(index.row() == 1)//blue row
painter->fillRect(option.rect,QColor(0,0,255));
else
if(index.row() == 2)//red row
painter->fillRect(option.rect,QColor(255,0,0));
//and so on
if( option.state & QStyle::State_Selected )//we need this to show selection
{
painter->fillRect( option.rect, option.palette.highlight() );
}
QStyledItemDelegate::paint(painter,option,index);//standard processing
}
Usage:
ui->tableView->setItemDelegate(new ItemDelegatePaint);
Result: