0

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

我尝试了基于 QTableWidgets 的类似片段的小部件上的 CSS 样式的不同组合,但没有成功。

知道如何更改此背景颜色吗?

在此处输入图像描述

编辑:鉴于提议的解决方案不起作用,我已经针对您的测试寻找可能的差异。这可能是由于使用了自定义 QStyledItemDelegate 我从How to display partial bold text in QListWidgetItem with QtCore.Qt.UserRole 中得到

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, option.palette.color(
                QtGui.QPalette.Active, QtGui.QPalette.Text))
        textRect = style.subElementRect(QtWidgets.QStyle.SE_ItemViewItemText, options, None)
        if index.column() != 0:
            textRect.adjust(5, 0, 0, 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, option, index):
        return QtCore.QSize(self.doc.idealWidth(), self.doc.size().height())

因此,我想我应该修改为 QPalette 设置颜色的部分。尽管如此,这里没有使用 QStyle::State_HasFocus,所以我不明白为什么它不起作用。现在知道如何修复它吗?

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

4

2 回答 2

1

可设置::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_())
于 2020-10-14T08:38:51.517 回答
1

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

调色板对样式表一无所知,实际上恰恰相反:样式表使用调色板(实际上,您可以在样式表中使用调色板角色)。无法以编程方式访问样式表中使用的颜色

你有两种可能:

  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:
            # ...
于 2020-10-14T15:18:34.143 回答