如何更改(删除)QListWidget 的 selection/active 颜色

How to change (remove) selection/active color of QListWidget

在我的 QListWidget 中,有些项目没有默认背景颜色,我在自定义 QListWidget class:

中这样设置它们
item->setBackgroundColor(qcolor); // item is of type QListWidgetItem*

我设置的那些非默认颜色被QListWidget的选择颜色扭曲了。看一个例子:

项目 threefour 应该是相同的颜色,但它们不是因为选择了项目 four,因此结果颜色是原始颜色的总和颜色和 QListWidget 的选择(活动项目?)颜色。

我的问题是如何编辑或删除该选择颜色?

我在我的 QListWidget 中试过(当我想更改项目的背景颜色时在特殊插槽中):

QPalette pal = this->palette();
pal.setColor(QPalette::Highlight, QColor(255,255,255,0));
this->setPalette(pal); // updated

但是没有产生任何效果。我究竟做错了什么?设置的变量是否正确?我是在 QListWidget 内部还是在其委托内部进行设置?

更新:我尝试使用 comment/answer 指出的样式表,但是,我的应用程序无法使用它们,因为我行中的项目有 3 个状态(所以我需要使用三种颜色)。例如,对应三种颜色的 3 种状态:粉色表示活动,绿色表示不活动,灰色表示其余。使用样式表时,我无法将自定义 属性(比方说 QListWidget::item[Inactive="true"])设置为单个 QListWidgetItem,但对于完整的 QListWidget,因此它为所有行着色相同的颜色。

针对类似问题 here 尝试了样式表,但没有奏效,因此我得出结论,使用样式表不是可行的方法。

我最初使用的背景更改方法对我的目的来说效果很好,但我不知道如何去掉默认选择颜色(透明浅蓝色),它添加到背景颜色并产生混合颜色。

我认为您最好使用 sheets 样式来执行此操作。这是一个例子

QListWidget::item
{
    background: rgb(255,255,255); 
}
QListWidget::item:selected
{
    background: rgb(128,128,255);
}

::item 表示 QListWidget 中的单个项目,而 :selected 表示当前 QListWidgetItems已选中。

然后要获得特定小部件的自定义背景,您可以使用自定义样式 sheet 属性。在你的代码中,在你想要应用自定义样式的小部件上调用类似这样的东西:

myList->setProperty( "Custom", "true" );

//  Updates the style.
style->unpolish( myList );
style->polish( myList );

然后在您的样式 sheet 中,像这样为您的自定义 属性 定义样式。

QListWidget::item[Custom="true"]
{
    background: rgb(128,255,128);
}

我通过委托找到了合适的解决方案。所以,没有必要使用 QPalette;对于我的问题,样式表将不起作用。当需要将不同的行(QListWidgetQTreeWidget)着色为不同的颜色时,此解决方案也适用,具体取决于某些状态。

背景颜色按照问题中的描述设置:

item->setBackgroundColor(qcolor); // change color slot inside QListWidget class

为了定义小部件的绘制规则,我重新定义了委托:

class Delegate : public QStyledItemDelegate {};

那我重新定义Delegate的方法paint()。在那里我定义了如何绘制我的小部件的每一行。更具体地说,我只在鼠标悬停在某个项目上时调用自定义绘图,或者该项目处于选中状态(这些是我想要避免的浅蓝色选中该行的情况)。代码如下所示:

void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if((option.state & QStyle::State_Selected) || (option.state & QStyle::State_MouseOver))
    {
        // get the color to paint with
        QVariant var = index.model()->data(index, Qt::BackgroundRole);

        // draw the row and its content
        painter->fillRect(option.rect, var.value<QColor>());
        painter->drawText(option.rect, index.model()->data(index, Qt::DisplayRole).toString());
    }
    else
        QStyledItemDelegate::paint(painter, option, index);

    // ... 
}

当然不要忘记将QListWidgetDelegate联系起来:

listWidget->setItemDelegate(new Delegate());