QHeaderView::paintSection 做了什么,以至于我在之前或之后对画家所做的一切都被忽略了

2021-12-09 00:00:00 qt qpainter c++ qheaderview

这个问题是这篇文章 是不同的,虽然看起来与 这个.

This question is further development of this post and is different, though may seem similar as this one.

我正在尝试重新实现 QHeaderView::paintSection,以便从模型返回的背景得到尊重.我试着这样做

I am trying to reimplement QHeaderView::paintSection, so that the background returned from the model would be honored. I tried to do this

void Header::paintSection(QPainter * painter, const QRect & rect, int logicalIndex) const
{
    QVariant bg = model()->headerData(logicalIndex, Qt::Horizontal, Qt::BackgroundRole);
    // try before
    if(bg.isValid())                // workaround for Qt bug https://bugreports.qt.io/browse/QTBUG-46216
        painter->fillRect(rect, bg.value<QBrush>());             
    QHeaderView::paintSection(painter, rect, logicalIndex);
    // try after
    if(bg.isValid())                // workaround for Qt bug https://bugreports.qt.io/browse/QTBUG-46216
        painter->fillRect(rect, bg.value<QBrush>());             
}

但是,它不起作用 - 如果我调用 QHeaderView::paintSection ,我用画家绘制的任何东西都不可见(我也尝试绘制对角线).如果我删除 QHeaderView::paintSection 调用,线条和背景将可见.在 QHeaderView::paintSection 之前和之后调用 fillRect 没有任何区别.

However, it didn't work - if I make QHeaderView::paintSection call, nothing I draw with the painter is visible (I also tried drawing a diagonal line). If I remove QHeaderView::paintSection call, the line and the background will be visible. Making the fillRect call before vs. after the QHeaderView::paintSection doesn't make any difference.

我想知道,QHeaderView::paintSection 是什么让我无法在它上面画一些东西.以及是否有一种方法可以在不重新实现 QHeaderView::paintSection 所做的一切的情况下克服它?

I wonder, what is it that QHeaderView::paintSection does that makes it impossible for me to draw something on top of it. And whether there is a way to overcome it without reimplementing everythning what QHeaderView::paintSection does?

我需要做的就是为某个单元格添加某种阴影 - 我仍然希望单元格中的所有内容(文本、图标、渐变背景等)都按照现在的方式绘制...

All I need to do is to add a certain shade to a certain cell - I still want everything in the cell (text, icons, gradient background etc.) to be painted as it is now...

推荐答案

很明显为什么第一个 fillRect 不起作用.您在 paintSection 之前绘制的所有内容都将被基础绘制覆盖.

It is obvious why the first fillRect doesn't work. Everything that you paint before paintSection is overridden by base painting.

第二个调用更有趣.

通常所有的绘制方法都会保留 painter 状态.这意味着当你调用 paint 时,它看起来像画家状态没有改变.

Usually all paint methods preserves painter state. It means that when you call paint it looks like the painter state hasn't been changed.

尽管如此,QHeaderView::paintSection 破坏了画家的状态.

Nevertheless QHeaderView::paintSection spoils the painter state.

要绕过这个问题,您需要自己保存和恢复状态:

To bypass the issue you need to save and restore the state by yourself:

void Header::paintSection(QPainter * painter, const QRect & rect, int logicalIndex) const
{
    QVariant bg = model()->headerData(logicalIndex, Qt::Horizontal, Qt::BackgroundRole);
    painter->save();
    QHeaderView::paintSection(painter, rect, logicalIndex);
    painter->restore();
    if(bg.isValid())               
        painter->fillRect(rect, bg.value<QBrush>());             
}

相关文章