Reputation:
I am trying to change the background color for certain header sections. Some will use the default coloring, others will get a different color.
The HeaderView doesn't accept delegates like the QTreeView does; it does all the painting itself. It does this using two methods --
My initial attempt was to try and override paintSection, letting it paint the default stuff, and then adding my own.
def paintSection(self, painter, rect, logicalindex):
QHeaderView.paintSection(self, painter, rect, logicalindex)
painter.save()
painter.fillRect(rect, QBrush(Qt.red))
painter.restore()
This doesn't appear to do anything. It will not draw the filled rect. If I comment out the call to the base paintSection method, it will draw the filled rect, but not very consistently (i.e. clicking and resizing the header causes it to fill sometimes and not others).
Any help is appreciated.
Upvotes: 1
Views: 7218
Reputation: 9764
There is no need to implement anythingQHeaderView
can be changed through stylesheets like almost all widgets.
Edit:
You mentioned that you wanted to change the background color per column depending on data, the easiest way to do that is probably to derive a new model from QAbstractItemModel
or another model class and reimplement the headerData()
call
QVariant QAbstractItemModel::headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const [virtual]
the role that you want to react to is Qt::BackgroundColorRole
so the function could look like this
QVariant VariableHeaderModel::headerData(int section Qt::Orientation orientation, int role)
{
QVariant result;
if (role == Qt::BackgroundColorRole)
{
result = <QColor from custom processing>
}
else
{
result = Superclass::headerData(section, orientation, role);
}
return result;
}
Generally in Qt, the model decides what to show, almost all of the times change the model, not the view. Also the 'data()' calls get called a lot, I don't know about the 'headerData()' but you probably want to cache any results if there is a lot of calculation going on.
If you are using the QStandardItemModel
you can probably just call
setHeaderData(section, orientation, <aColor>, Qt::BackgroundColorRole);
Upvotes: 2
Reputation: 8958
I agree with "Harald Scheirich" style sheets are the way to go. But perhaps to convince you I will tell you about a lesser known part of stylesheets called Property Selectors
If you take a look at the stylesheet doc here, you'll see a small section about them. Basically what we are doing is specifying a stylesheet for those widgets with a particular property set. For instance, all QPushButtons that are flat.
QPushButton[flat="true"]
{
background-color: blue
}
Now while that is pretty cool, on it's own it doesn't really help you. What is even more amazing is that you can add your own properties to a QObject. These are known as dynamic properties. And these can also be used in property selectors
So I could create a stylesheet like this - where highlightHeader is my made-up property
QHeaderView[highlightHeader="true"]
{
background-color: red
}
Now, you can apply this style sheet globally to every QHeaderView. But since no one is setting highlightHeader to true, we won't see any red anywhere. So the next step is when we decide that we want to make a particular QHeaderView red, then we call this:
myHeaderView->setProperty("highlightHeader", true);
myHeaderView->style()->unpolish(myHeaderView);
myHeaderView->style()->polish(myHeaderView);
In the first line we are setting the property to trigger the state that we want. The next two lines are to ensure that Qt re-evaluates the style of the widget. Otherwise you probably won't see the change.
And basically that's it. I hope that helps.
Upvotes: 0