【问题标题】:How can I get the background color returned by model take precedence over the style如何让模型返回的背景颜色优先于样式
【发布时间】:2015-07-22 03:35:10
【问题描述】:

我有一个QTreeView 渲染QAbstractItemModel,我想根据模型中的数据设置某些单元格的背景。我从model::data(Qt::BackgroundColorRole) 返回QBrush,直到我将样式应用于项目。

为项目设置任何样式(甚至与背景颜色无关的内容,例如设置边框样式)都会覆盖我从模型返回的颜色(对模型进行查询背景颜色的调用)。 IE。视图的行为就像模型从不返回任何颜色一样。

我使用的是 Qt 4.8,无法升级到更高版本。

有没有办法让模型返回的颜色优先于样式? 为什么 Qt 会以如此奇怪的方式表现 - 模型具有更多的粒度,并且比样式可能知道的更多,为什么样式优先 - 毕竟,模型不必为每一个返回颜色单元格 - 只有几个特定的​​单元格?

我认为这是 Qt 中的一个错误,我打开了一个 bug report,可以在此代码上重现:

#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();
}

如果你在返回之前取消注释该行,所有的背景都消失了。

【问题讨论】:

  • 也许为小部件设置 WA_NoSystemBackground 标志有帮助?
  • 感谢您的建议,但它没有帮助 - 我尝试在小部件上设置属性,还设置 WA_NoBackground 和取消设置 WA_StyledBackground,但没有任何帮助 - 一旦我加载样式,所有从模型返回的背景丢失了...
  • 它甚至会尝试读取后台角色的数据吗?
  • 是的——断点经常被命中

标签: qt qtreeview qtstylesheets qabstractitemmodel


【解决方案1】:

我找到了一个解决方法——它仍然是一些额外的代码,恕我直言,它应该由 Qt 本身处理,但至少有一种方法可以用默认渲染覆盖背景,即我不需要重新实现默认委托 (QStyledItemDelegate) 所做的一切:

    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),它会很好地覆盖在样式的背景上,这样交替行着色或类似的东西仍然可见。

不过,有趣的是,我还对标题应用了相同的技巧(在重新实现的 QHeaderView::paintSection 中),但它不起作用 - 只要我不调用 QHeaderView::paintSection,我的背景就可见 - 如果我这样做,我的painter-&gt;fillRect 呼叫被忽略。我会把它作为一个单独的问题发布。

【讨论】:

猜你喜欢
  • 2010-10-20
  • 2011-03-29
  • 2011-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
相关资源
最近更新 更多