Reputation: 2184
I've been trying to use a "per-cell" custom background in a (custom) QTableView
using a (custom) QStyledItemDelegate
. Everything works well, until I actually try to have my custom background. Let's say for the sake of example, I want all my cells to have a red background. Here's the paint
method of my Delegate
.
QStyleOptionViewItem newOption = option;
auto normalText = newOption.palette.brush(QPalette::ColorGroup::Normal, QPalette::ColorRole::Text);
// Works as expected
newOption.palette.setBrush(QPalette::ColorGroup::Normal, QPalette::ColorRole::Highlight, Qt::gray); // QBrush(Qt::GlobalColor::blue, Qt::BrushStyle::NoBrush));
// Expected too: selected cells are gray
newOption.palette.setBrush(QPalette::ColorGroup::Normal, QPalette::ColorRole::HighlightedText, normalText);
// All of the following do NOT work. I've tried every possible combination without success.
newOption.palette.setBrush(QPalette::ColorGroup::Normal, QPalette::ColorRole::Window, Qt::red);
newOption.palette.setBrush(QPalette::ColorGroup::Inactive, QPalette::ColorRole::Base, Qt::red);
newOption.palette.setBrush(QPalette::ColorGroup::Inactive, QPalette::ColorRole::AlternateBase, Qt::red);
newOption.palette.setBrush(QPalette::ColorGroup::Active, QPalette::ColorRole::Base, Qt::red);
newOption.palette.setBrush(QPalette::ColorGroup::Active, QPalette::ColorRole::AlternateBase, Qt::red);
QStyledItemDelegate::paint(painter, newOption, index);
How am I supposed to achieve that? I thought my way of doing it was rather simple and intuitive... What's wrong here?
Upvotes: 2
Views: 1504
Reputation: 243983
Your code has the following errors:
Do not use the paint()
method if you want to customize the properties of the QStyleOptionViewItem
since within the paint()
method it will be overwritten by the initStyleOption()
method that is called internally.
Not all the properties of the painting are obtained from QPalette
, in the case of the background color you must use the backgroundBrush
property.
Considering the above the solution is:
#include <QtWidgets>
class StyledItemDelegate: public QStyledItemDelegate
{
public:
using QStyledItemDelegate::QStyledItemDelegate;
protected:
void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override
{
QStyledItemDelegate::initStyleOption(option, index);
QBrush normalText = option->palette.brush(QPalette::ColorGroup::Normal, QPalette::ColorRole::Text);
option->palette.setBrush(QPalette::ColorGroup::Normal, QPalette::ColorRole::Highlight, Qt::gray);
option->palette.setBrush(QPalette::ColorGroup::Normal, QPalette::ColorRole::HighlightedText, normalText);
option->backgroundBrush = QColor(Qt::red);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTableView w;
StyledItemDelegate *delegate = new StyledItemDelegate(&w);
w.setItemDelegate(delegate);
QStandardItemModel model(10, 10);
w.setModel(&model);
w.show();
return a.exec();
}
Upvotes: 5
Reputation: 16856
I know it's troublesome, but if you step through the source of QStyledItemDelegate::paint()
, deep down inside you'll find some hard-coded values there (e.g. background color of selected items).
I ended up drawing over instead of under the QStyledItemDelegate::paint()
with a semi-transparent painter / brush / image (after the base class call).
If the selection behavior isn't important to you, try performing the painting yourself before calling QStyledItemDelegate::paint()
and see if that suits your needs.
Upvotes: 0