问题描述
我有一个QTreeView
渲染QAbstractItemModel
,在这里我想根据模型中的数据设置某些单元格的背景.我从model::data(Qt::BackgroundColorRole)
返回QBrush
,直到我将样式应用于项目为止.
I have a QTreeView
rendering QAbstractItemModel
, where I would like to set the background of certain cells based on the data in the model. I return QBrush
from model::data(Qt::BackgroundColorRole)
and it works until I apply a style to an item.
为项目设置任何样式(甚至与背景颜色无关的任何东西,例如设置边框样式)都将覆盖我从模型返回的颜色(进行了对查询背景颜色的模型的调用). IE.视图的行为就像模型永远不会返回任何颜色一样.
Setting any style to the item (even something that has nothing to do with background color, e.g. styling the border) overrides the color I return from the model (the calls to the model querying the background color are made). I.e. the view behaves as if the model never returns any color.
我正在使用Qt 4.8,无法升级到更高版本.
I am using Qt 4.8 and I cannot upgrade to a later version.
是否有办法使模型返回的颜色优先于样式?为什么Qt表现得如此奇怪-模型具有更精细的粒度,并且比样式可能知道的更多的信息,为什么样式优先-毕竟,模型不必为每个单个颜色返回颜色单元格-只有几个特定的单元格?
Is there a way to make the color returned from the model take precedence over the style?Why does the Qt behave in such a strange way - model has way more granularity and knows way more than a style can possibly know, why does the style take precedence - after all, the model doesn't have to return the color for every single cell - only a few specific ones?
我认为这是Qt中的错误,我打开了错误报告 ,此代码可重现:
I assume it is a bug in Qt, I have opened a bug report, which is reproducible on this code:
#include <QtCore/qabstractitemmodel.h>
#include <QtGui/qtreeview.h>
#include <QtGui/qtableview.h>
#include <QtGui/qapplication.h>
class MyModel : public QAbstractItemModel
{
public:
MyModel(QObject *parent) :QAbstractItemModel(parent){}
int rowCount(const QModelIndex &parent = QModelIndex()) const
{ return 2; }
int columnCount(const QModelIndex &parent = QModelIndex()) const
{ return parent.isValid() ? 0 : 2; }
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
{
if(index.row() >= 0 && index.column() >= 0)
{
switch(role)
{
case Qt::DisplayRole:
return QString("a");
case Qt::BackgroundRole:
return QBrush(QColor(255 * index.row(), 255 * index.column(), 0));
default:
break;
}
}
return QVariant();
}
virtual QModelIndex index(int pos, int column, const QModelIndex &parent = QModelIndex()) const
{ return createIndex(pos, column, 0); }
virtual QModelIndex parent(const QModelIndex &child) const
{ return QModelIndex(); }
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTreeView view;
MyModel myModel(0);
view.setModel(&myModel);
view.show();
//a.setStyleSheet("QTreeView::item { border: 1px solid black; }");
return a.exec();
}
如果在返回之前取消注释该行,则所有背景都将消失.
If you uncomment the line before return, all the backgrounds are gone.
推荐答案
我找到了一种解决方法-它仍然是一些额外的代码,恕我直言,它应该由Qt本身处理,但是至少有一种方法可以覆盖默认渲染的背景,即我不需要重新实现默认委托(QStyledItemDelegate
)所做的所有事情:
I found a workaround - it still is some extra code and IMHO it should have been handled by the Qt itself, but at least there is a way to overlay the background with the default rendering, i.e. I don't need to reimplement everything the default delegate (QStyledItemDelegate
) does:
void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QVariant bg = index.data(Qt::BackgroundRole);
if(bg.isValid()) // workaround for Qt bug https://bugreports.qt.io/browse/QTBUG-46216
painter->fillRect(option.rect, bg.value<QBrush>());
QStyledItemDelegate::paint(painter, option, index);
}
如果模型返回的背景有些透明(我使用的alpha值为50),则可以很好地覆盖样式的背景,这样仍然可以看到交替行的着色或类似内容.
If the background returned by the model is somewhat transparent (I used alpha-value of 50), it is nicely overlaid over the style's background, so that alternate-row coloring or similar stuff is still visible.
不过,有趣的是,我还对标头应用了同样的技巧(在重新实现的QHeaderView::paintSection
中),但是它不起作用-只要不调用QHeaderView::paintSection
,我的背景就可见-如果可以,我的painter->fillRect
调用将被忽略.我将其作为一个单独的问题发布.
Interesting, though, I also applied the same trick to the header (in reimplemented QHeaderView::paintSection
) and it didn't work - my background is visible as long as I don't call QHeaderView::paintSection
- if I do, my painter->fillRect
call is ignored. I'll post it as a separate question.
这篇关于如何获得模型返回的背景颜色优先于样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!