2

In my QListWidget, there are some items that have non-default background color, I set them like so inside the custom QListWidget class:

item->setBackgroundColor(qcolor); // item is of type QListWidgetItem*

Those non-default colors that I set are distorted by the QListWidget's selection color. See an example:

enter image description here

Items three and four are supposed to be the same color, but they are not since the item four is selected, and thus the result color is a summation of original color and QListWidget's selection (active item?) color.

My question is how to edit or remove that selection color?

I tried inside my QListWidget (in special slot when I want to change the item's background color):

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

But it did not produce any effect. what am I doing wrong? Is it a correct variable to set? Do I set it up inside QListWidget or inside its delegate?

Update: I tried using stylesheets as pointed by comment/answer, however, it will not be possible to use them for my application, because the items in my rows have 3 states (so I would need to use three colors). E.g., 3 states that correspond to three colors: pink for active, green for inactive and gray for the rest. When using stylesheets, I cannot set the custom property (let's say QListWidget::item[Inactive="true"]) to a single QListWidgetItem, but for the full QListWidget, and therefore it colors all the rows the same color.

Stylesheets were tried for similar problem here, and didn't work, therefore I make conclusion using stylesheets is not the way to go.

The background change method that I used originally works fine for my purpose, but I cannot figure out how to get rid of the default selection color (transparent light blue) which adds to the background color and produces the mixed color.

4

2 回答 2

5

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

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

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

然后获取特定小部件的自定义背景,您可以使用自定义样式表属性。在您的代码中,在您要应用自定义样式的小部件上调用类似的内容:

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

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

然后在您的样式表中,为您的自定义属性定义样式,如下所示。

QListWidget::item[Custom="true"]
{
    background: rgb(128,255,128);
}
于 2016-03-15T18:34:17.360 回答
2

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

背景颜色的设置如问题所述:

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);

    // ... 
}

当然,不要忘记将 with 关联QListWidget起来Delegate

listWidget->setItemDelegate(new Delegate());
于 2016-04-30T18:05:36.070 回答