Qt6:禁用 QTreeView 项目的默认背景绘制

问题描述 投票:0回答:1

在 Qt 6.5 之前,仅当指定了项目的交替背景时才会渲染项目背景,从而允许

QStyledItemDelegate
独立渲染背景。然而,这已被 qt/qtbase@16e0e7c 提交更改。

编辑:我发现了另一个属于此回归的提交:qt/qtbase@483ae6c。这个将

PanelItemViewRow
s 转换为
PanelItemViewItem
s 来“正确”渲染背景,因为它是不可从 qss 设置样式的。我不知道为什么这样做而不是在 qss 中引入像
::row
这样的东西。

一种解决方案是使用

PE_PanelItemViewRow
覆盖
QProxyStyle
但这不适用于样式表,这是硬性要求,因为应用程序允许自定义样式。

另一种可能性是在 qss 中将

::item
设置为没有背景,并以某种方式在
QStyledItemDelegate
中渲染它,但我不知道如何以可以使用 qss 控制它的方式进行操作。

不正确的行为:

Incorrect behavior

预期的一个:

Expected behavior

qt qtreeview qt6 qstyleditemdelegate
1个回答
0
投票

我设法找到了解决这个问题的办法。

要禁用背景渲染,我可以在 Qt 中滥用此 if 语句:

        // For compatibility reasons, QTreeView draws different parts of
        // the background of an item row separately, before calling the
        // delegate to draw the item. The row background of an item is
        // however not separately styleable through a style sheet, but
        // only indirectly through the background of the item. To get the
        // same background for all parts drawn by QTreeView, we have to
        // use the background rule for the item here.
        if (renderRule(w, opt, PseudoElement_ViewItem).hasBackground())
            pseudoElement = PseudoElement_ViewItem;

因此禁用

::item
的背景会禁用分支和不需要的背景的渲染(我正在使用qtsass):

  QTreeView::item {
    &, &:selected, &:hover {
      background: none;
      border: none;
    }
  }

然而,这使我无法定义 qss 的背景。但作为一种解决方法,我在委托内部创建了人工 QTreeView 小部件,并带有一些定义良好的对象名称,在我的情况下为

DocumentTreeItems

TreeWidgetItemDelegate::TreeWidgetItemDelegate(QObject* parent)
    : QStyledItemDelegate(parent)
{
    artificial = new QTreeView(qobject_cast<QWidget*>(parent));
    artificial->setObjectName("DocumentTreeItems");
    artificial->setFixedSize(0, 0);
}

感谢我可以将样式附加到 qss 内的这个小部件:

  #DocumentTree::item {
    border: 1px solid transparent;
    border-radius: 2px;
    background-color: $primaryBackground;

    &:hover {
      border: 1px solid $contrastBorder;
      background-color: $controlWidgetBackground;
    }

    &:selected {
      border: 1px solid $accentBorder;
      background-color: $accentBackground;
    }
  }

然后我可以使用样式重新绘制背景,并在委托的

paint
方法中引用我的人工小部件:

    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, artificial);

这给出了预期的结果:

enter image description here

但是我对这个解决方案非常不满意,所以如果有人知道更好的解决方案,我会很高兴听到建议。

© www.soinside.com 2019 - 2024. All rights reserved.