简体   繁体   English

如何自动更改 QListWidget 中所选项目的颜色

[英]how to automatically change the color of selected item in QListWidget

I want to change the color of selected item in QListItem, and I find qss may be a solution.我想更改 QListItem 中所选项目的颜色,我发现 qss 可能是一个解决方案。 And the code is:代码是:

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import sys

class Window(QWidget):

    def __init__(self):
        super().__init__()
        with open('mainStyle.qss', 'r', encoding='utf-8') as file:
            self.setStyleSheet(file.read())
        # self.setStyleSheet('*{font-size: 15px;background-color: rgb(150, 150, 150);}'
        #                    'QListWidget::item:selected{background: rgb(128,128,255);}')
        self.setStyleSheet('QListWidget::item:selected{background: rgb(128,128,255);}')

        layout = QVBoxLayout()
        self.setLayout(layout)

        listWidget = QListWidget()
        layout.addWidget(listWidget)

        w1 = QWidget()
        w1Item = QListWidgetItem()
        w1Item.setSizeHint(QSize(150, 150))

        listWidget.insertItem(0, w1Item)
        listWidget.setItemWidget(w1Item, w1)

        w2 = QWidget()
        w2Item = QListWidgetItem()
        w2Item.setSizeHint(QSize(150, 150))

        listWidget.insertItem(1, w2Item)
        listWidget.setItemWidget(w2Item, w2)


if __name__ == '__main__':

    app = QApplication(sys.argv)
    win = Window()
    win.show()
    app.exec_()

在此处输入图像描述

We can see that the color is changed to be blue when the item is selected.我们可以看到,当项目被选中时,颜色变为蓝色。

However, I need to provide a general background color for other widgets.但是,我需要为其他小部件提供一般背景颜色。 So I change the style from所以我改变了风格

self.setStyleSheet('QListWidget::item:selected{background: rgb(0,0,255);}')

to

self.setStyleSheet('*{font-size: 15px;background-color: rgb(150, 150, 150);}'
                   'QListWidget::item:selected{background: rgb(0,0,0);}')

Then, I find QListWidget::item:selected do not work.然后,我发现QListWidget::item:selected不起作用。 The color do not change when I select a item.当我 select 一个项目时颜色不改变。

What's the wrong with my code?我的代码有什么问题?

The problem is that you're setting a QWidget for the item, and since you're using a universal selector (with the wildcard), the result is that all QWidget will have that background color, including those added as item widgets for the list view.问题是您正在为该项目设置一个 QWidget,并且由于您使用的是通用选择器(带有通配符),结果是所有QWidget 都将具有该背景颜色,包括那些作为项目小部件添加的列表看法。
The color you used for the :selected pseudo is only valid for the item painted by the view, since the item widget has its own background set from the universal selector, that background won't be visible.您用于:selected伪的颜色仅对视图绘制的项目有效,因为项目小部件从通用选择器中设置了自己的背景,因此该背景将不可见。

The solution is to use a proper selector combination ensuring that the rule only matches children of the list view that have a usable selector, and set a transparent color for those widgets.解决方案是使用适当的选择器组合,确保规则仅匹配具有可用选择器的列表视图的项,并为这些小部件设置透明颜色。

A possibility is to set a custom property for the widgets that must be set before adding the widgets to the list (otherwise, you need to set the stylesheet after adding them, or request a style.unpolish() ).一种可能性是为小部件设置自定义属性,在将小部件添加到列表之前必须设置该属性(否则,您需要在添加它们之后设置样式表,或者请求style.unpolish() )。

        self.setStyleSheet('''
            QWidget {
                font-size: 15px;
                background: rgb(150, 150, 150);
            }
            QListWidget::item:selected {
                background: rgb(128,128,255);
            }
            QListWidget QWidget[widgetItem=true] {
                background: transparent;
            }
        ''')

        # ...
        w1 = QWidget()
        w1.setProperty('widgetItem', True)
        # ...
        w2 = QWidget()
        w2.setProperty('widgetItem', True)
        # ...

Another way to do so is to use an "empty" subclass for widgets that are going to be added to the item view:另一种方法是为要添加到项目视图的小部件使用“空”子类:

class CustomItemWidget(QWidget): pass

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setStyleSheet('''
            QWidget {
                font-size: 15px;
                background: rgb(150, 150, 150);
            }
            QListWidget::item:selected {
                background: rgb(128,128,255);
            }
            CustomItemWidget {
                background: transparent;
            }
        ''')

        # ...
        w1 = CustomItemWidget()
        # ...
        w2 = CustomItemWidget()
        # ...

Consider that using universal selectors for colors is usually not a good idea, as it can result in inconsistent behavior, especially for complex widgets: for instance, the scroll bars of scroll areas (like QListWidget) might not be correctly styled and can even become unusable.考虑为 colors 使用通用选择器通常不是一个好主意,因为它可能导致不一致的行为,特别是对于复杂的小部件:例如,滚动区域(如 QListWidget)的滚动条可能没有正确设置样式,甚至可能变得不可用.
If you plan to have a common background color for all widgets, it's better to set the Window role of the application palette:如果您打算为所有小部件使用通用背景颜色,最好设置应用程序调色板的Window角色:

    app = QApplication(sys.argv)
    palette = app.palette()
    palette.setColor(palette.Window, QColor(150, 150, 150))
    app.setPalette(palette)
    # ...

In this way the current style will know exactly when to use that color as background, or as a component for other UI elements.通过这种方式,当前样式将准确地知道何时将该颜色用作背景,或用作其他 UI 元素的组件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM