I have a QTreeView
and want different background colors for rows, depending on their content. To achieve this, I derived a class MyTreeView
from QTreeView
and implemented the paint method as follows:
void MyTreeView::drawRow (QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
QStyleOptionViewItem newOption(option);
if (someCondition)
{
newOption.palette.setColor( QPalette::Base, QColor(255, 0, 0) );
newOption.palette.setColor( QPalette::AlternateBase, QColor(200, 0, 0) );
}
else
{
newOption.palette.setColor( QPalette::Base, QColor(0, 0, 255) );
newOption.palette.setColor( QPalette::AlternateBase, QColor(0, 0, 200) );
}
QTreeView::drawRow(painter, newOption, index);
}
Initially, I set setAlternatingRowColors(true);
for the QTreeView.
My problem: Setting the color for QPalette::Base has no effect. Every second row remains white.
However, setting QPalette::AlternateBase works as expected.
I tried setAutoFillBackground(true)
and setAutoFillBackground(false)
without any effect.
Are there any hints how to solve this problem? Thank you.
Remark: Setting the color by adapting MyModel::data(const QModelIndex&, int role)
for Qt::BackgroundRole
does not provide the desired result. In this case, the background color is used only for a part of the row. But I want to color the full row, including the left side with the tree navigation stuff.
Qt Version: 4.7.3
Update:
For unknown reasons QPalette::Base
seems to be opaque.
setBrush does not change that.
I found the following workaround:
if (someCondition)
{
painter->fillRect(option.rect, Qt::red);
newOption.palette.setBrush( QPalette::AlternateBase, Qt::green);
}
else
{
painter->fillRect(option.rect, Qt::orange);
newOption.palette.setBrush( QPalette::AlternateBase, Qt:blue);
}
If the only problem is that the expanding/collapsing controls do not have a background like rest of the row then use Qt::BackgroundRole
in ::data()
of your model (as described by pnezis in their answer) and add this to your tree view class:
void MyTreeView::drawBranches(QPainter* painter,
const QRect& rect,
const QModelIndex& index) const
{
if (some condition depending on index)
painter->fillRect(rect, Qt::red);
else
painter->fillRect(rect, Qt::green);
QTreeView::drawBranches(painter, rect, index);
}
I've tested this on Windows (Vista and 7) using Qt 4.8.0 and expanding/collapsing arrows have proper background. The problem is that those arrows are part of the view and thus cannot be handled in a model.
Instead of subclassing QTreeView
you should handle the background color through your model. Use the data()
function and the Qt::BackgroundRole
for changing the background color of the rows.
QVariant MyModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role == Qt::BackgroundRole)
{
if (condition1)
return QColor(Qt::red);
else
return QColor(Qt::green);
}
// Handle other roles
return QVariant();
}
https://www.linux.org.ru/forum/development/4702439
if ( const QStyleOptionViewItemV4* opt = qstyleoption_cast<const QStyleOptionViewItemV4*>(&option) )
{
if (opt.features & QStyleOptionViewItemV4::Alternate)
painter->fillRect(option.rect,option.palette.alternateBase());
else
painter->fillRect(option.rect,painter->background());
}
来源:https://stackoverflow.com/questions/14255224/changing-the-row-background-color-of-a-qtreeview-does-not-work