PyQt5:在列表失去焦点时设置QListWidget选择颜色

问题描述

我已经编写了一个带有两个QListWidgets的小型PyQt5应用程序,如图所示。为了获得具有背景色的组合框,我设置了“融合”样式,作为不希望的结果,我遇到了QListWidget选择颜色的问题:选择具有焦点时具有蓝色背景,这很好,但是会变亮列表失去焦点时会显示为灰色背景(如左侧列表中所示),使其难以阅读。

我根据与QTableWidgets类似的片段,尝试对小部件使用CSS样式的不同组合,但没有成功。

关于如何更改此背景色的任何想法?

enter image description here

编辑:鉴于建议的解决方案不起作用,我一直在寻找与您的测试可能存在的差异。这可能是由于使用了我从How to display partially bold text in QListWidgetItem with QtCore.Qt.UserRole

获得的自定义qstyledItemDelegate
from PyQt5 import QtCore,QtGui,QtWidgets


class HTMLDelegate(QtWidgets.qstyledItemDelegate):
    '''
    The roles >= Qt::UserRole are not used by Qt by default so it can be used for any purpose,for example to save additional information,in this case it is not the solution.
    One possible solution is to use a delegate to render the HTML.
    (Extracted from https://stackoverflow.com/questions/53569768/how-to-display-partially-bold-text-in-qlistwidgetitem-with-qtcore-qt-userrole)
    '''
    def __init__(self,parent=None):
        super(HTMLDelegate,self).__init__(parent)
        self.doc = QtGui.QTextDocument(self)

    def paint(self,painter,option,index):
        painter.save()
        options = QtWidgets.qstyleOptionViewItem(option)
        self.initStyleOption(options,index)
        self.doc.setHtml(options.text)
        options.text = ""
        style = QtWidgets.QApplication.style() if options.widget is None \
            else options.widget.style()
        style.drawControl(QtWidgets.qstyle.CE_ItemViewItem,options,painter)

        ctx = QtGui.QAbstractTextDocumentLayout.PaintContext()
        if option.state & QtWidgets.qstyle.State_Selected:
            ctx.palette.setColor(QtGui.QPalette.Text,option.palette.color(
                QtGui.QPalette.Active,QtGui.QPalette.HighlightedText))
        else:
            ctx.palette.setColor(QtGui.QPalette.Text,QtGui.QPalette.Text))
        textRect = style.subElementRect(QtWidgets.qstyle.SE_ItemViewItemText,None)
        if index.column() != 0:
            textRect.adjust(5,0)
        constant = 4
        margin = (option.rect.height() - options.fontMetrics.height()) // 2
        margin = margin - constant
        textRect.setTop(textRect.top() + margin)

        painter.translate(textRect.topLeft())
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        self.doc.documentLayout().draw(painter,ctx)
        painter.restore()

    def sizeHint(self,index):
        return QtCore.QSize(self.doc.idealWidth(),self.doc.size().height())

因此,我想我应该修改QPalette设置颜色的部分。但是,这里没有使用qstyle :: State_HasFocus,所以我不明白为什么它不起作用。关于现在如何解决的任何想法?

作为一个平行的问题:QT小部件及其子元素的所有CSS可能性的定义在哪里?我希望能够自己探索它,而不是将来会遇到类似简单CSS代码的问题:)

解决方法

可以在::item子控件,:selected伪状态和:!active伪状态中进行设置。

QListWidget::item:selected:!active {
    background: #17d;
}

测试示例:

import sys
from PyQt5.QtWidgets import *

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyle('fusion')
    app.setStyleSheet('''
    QListWidget::item:selected:!active {
        background: lightBlue;
        color: black;
    }''')
    items = ['2020-11-27'] * 6
    x = QListWidget(); x.addItems(items)
    y = QListWidget(); y.addItems(items)
    window = QWidget()
    hbox = QHBoxLayout(window)
    hbox.addWidget(x); hbox.addWidget(y)
    window.show()
    sys.exit(app.exec_())
,

只要涉及使用QPalette颜色作为参考的自定义工程图,就不能依赖样式表:样式表覆盖样式,并且每当指定颜色时,调色板也会被忽略(至少对于状态/样式表中指定的属性)。

调色板对样式表一无所知,实际上是相反的:样式表使用调色板(实际上,您可以使用palette roles in stylesheets )。
没有方法来以编程方式访问样式表中使用的颜色。

您有两种可能性:

  1. 在没有焦点的情况下, 绘制项目之前,更改突出显示的项目的背景颜色:
        if not option.state & QtWidgets.QStyle.State_HasFocus:
            options.palette.setColor(QtGui.QPalette.Highlight,QtCore.Qt.darkGray)
        style.drawControl(QtWidgets.QStyle.CE_ItemViewItem,options,painter)
        # ...
  1. 仅在选择了并且有焦点时才设置文本颜色:
        if (option.state & QtWidgets.QStyle.State_Selected and 
            option.state & QtWidgets.QStyle.State_HasFocus):
                ctx.palette.setColor(QtGui.QPalette.Text,option.palette.color(
                    QtGui.QPalette.Active,QtGui.QPalette.HighlightedText))
        else:
            # ...

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...