Qt 模型/视图:如何使用模型中的前景项目颜色而不是样式表中的前景项目颜色

发布于 2025-01-11 11:38:08 字数 1971 浏览 3 评论 0原文

我有自定义模型,它返回 ForegroundRole 所需的前景色:

QVariant AlertTreeModel::data(const QModelIndex& index, int role) const
{
    if (!index.isValid())
    {
        return {};
    }

    const auto item = itemForIndex(index);
    switch (role)
    {    
        case Qt::ForegroundRole:
            return item->color(); // return different colors for the different item states

        default:
            return {};
    }
}

视图(位简化代码):

void UniformIndentationTreeView::drawRow(QPainter* painter, const QStyleOptionViewItem& options, const QModelIndex& index) const
{
    QStyleOptionViewItem opt = options;
    QTreeView::drawRow(painter, opt, index);
}

我还有简单的自定义委托,我可以在其中确保获得正确的前景色:

void AlertTreeViewItemDelegate::initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) const
{
    UniformIndentationItemViewDelegate::initStyleOption(option, index);

    QColor color = index.data(Qt::ForegroundRole).value<QColor>();

    INFOLOG << "tree item color = " << color.name(QColor::HexRgb);

    option->palette.setColor(QPalette::WindowText, color);
    option->palette.setColor(QPalette::HighlightedText, color);
}

问题是我的树使用样式表中的颜色进行绘制,并且不使用模型返回的颜色。如何强制视图/委托使用自定义前景色?

更新。在Qt源代码中我们可以看到QStyledItemDelegate::paint采用widget的样式来绘制控件。

void QStyledItemDelegate::paint(QPainter *painter,
        const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_ASSERT(index.isValid());
    QStyleOptionViewItem opt = option;
    initStyleOption(&opt, index);
    const QWidget *widget = QStyledItemDelegatePrivate::widget(option);
    QStyle *style = widget ? widget->style() : QApplication::style();
    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
}

如何使用模型中的颜色而不是样式表中的颜色绘制项目?

I have custom model that return necessary foreground color for the ForegroundRole:

QVariant AlertTreeModel::data(const QModelIndex& index, int role) const
{
    if (!index.isValid())
    {
        return {};
    }

    const auto item = itemForIndex(index);
    switch (role)
    {    
        case Qt::ForegroundRole:
            return item->color(); // return different colors for the different item states

        default:
            return {};
    }
}

View (bit simplified code):

void UniformIndentationTreeView::drawRow(QPainter* painter, const QStyleOptionViewItem& options, const QModelIndex& index) const
{
    QStyleOptionViewItem opt = options;
    QTreeView::drawRow(painter, opt, index);
}

I also have the simple custom delegate where I can ensure I get correct foreground color:

void AlertTreeViewItemDelegate::initStyleOption(QStyleOptionViewItem* option, const QModelIndex& index) const
{
    UniformIndentationItemViewDelegate::initStyleOption(option, index);

    QColor color = index.data(Qt::ForegroundRole).value<QColor>();

    INFOLOG << "tree item color = " << color.name(QColor::HexRgb);

    option->palette.setColor(QPalette::WindowText, color);
    option->palette.setColor(QPalette::HighlightedText, color);
}

The problem is that my tree is painted with colors from a style sheet and doesn't use the colors which the model returns. How to force view/delegate to use custom foreground color?

Update. In the Qt sources we can see that QStyledItemDelegate::paint take widget's style to draw controls.

void QStyledItemDelegate::paint(QPainter *painter,
        const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_ASSERT(index.isValid());
    QStyleOptionViewItem opt = option;
    initStyleOption(&opt, index);
    const QWidget *widget = QStyledItemDelegatePrivate::widget(option);
    QStyle *style = widget ? widget->style() : QApplication::style();
    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
}

How to draw items with colors from a model, not from a style sheet?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文