如何更改(删除)QListWidget 的 selection/active 颜色
How to change (remove) selection/active color of QListWidget
在我的 QListWidget
中,有些项目没有默认背景颜色,我在自定义 QListWidget
class:
中这样设置它们
item->setBackgroundColor(qcolor); // item is of type QListWidgetItem*
我设置的那些非默认颜色被QListWidget
的选择颜色扭曲了。看一个例子:
项目 three
和 four
应该是相同的颜色,但它们不是因为选择了项目 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
;对于我的问题,样式表将不起作用。当需要将不同的行(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);
// ...
}
当然不要忘记将QListWidget
与Delegate
联系起来:
listWidget->setItemDelegate(new Delegate());
在我的 QListWidget
中,有些项目没有默认背景颜色,我在自定义 QListWidget
class:
item->setBackgroundColor(qcolor); // item is of type QListWidgetItem*
我设置的那些非默认颜色被QListWidget
的选择颜色扭曲了。看一个例子:
项目 three
和 four
应该是相同的颜色,但它们不是因为选择了项目 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
;对于我的问题,样式表将不起作用。当需要将不同的行(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);
// ...
}
当然不要忘记将QListWidget
与Delegate
联系起来:
listWidget->setItemDelegate(new Delegate());