How do I achieve consistent highlighting of QListWidget items across widget states?
Asked Answered
S

3

8

I am using PyQT 4.8.3 to create a dialog with two QListWidgets both allowing multiple selection.

  1. I find that if these QListWidgets are enabled, the selected items are highlighted in blue only when the QListWidget has focus, without focus the highlight is light-grey.

  2. I also find that if the QListWidgets are disabled, the selected items are highlighted in blue despite lack of focus.

enter image description here

As the users go from one list to the other they will find this very confusing.

As a developer I find the light-grey/unfocused, blue/disabled behaviours undesirable. I would appreciate any advice on modifying them.

I've looked through the docs for QListWidget, QListView and QAbstractView without finding anything applicable, I have also looked through the stylesheet documentation without having any luck.

Schaab answered 15/1, 2013 at 3:20 Comment(0)
G
10

I would use stylesheets here. In this example, the selected items in this QListWidget will he highlighted in blue, and when the QListWidget is disabled or without focus they will turn gray:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from PyQt4 import QtCore, QtGui

class myWindow(QtGui.QWidget):

    def __init__(self, parent=None):
        super(myWindow, self).__init__(parent)

        self.setStyleSheet( """ QListWidget:item:selected:active {
                                     background: blue;
                                }
                                QListWidget:item:selected:!active {
                                     background: gray;
                                }
                                QListWidget:item:selected:disabled {
                                     background: gray;
                                }
                                QListWidget:item:selected:!disabled {
                                     background: blue;
                                }
                                """
                                )

        self.listWidget = QtGui.QListWidget(self)
        self.listWidget.setSelectionMode(QtGui.QAbstractItemView.MultiSelection)

        self.button = QtGui.QPushButton(self)
        self.button.setText("Disable the list!")
        self.button.clicked.connect(self.on_button_clicked)

        self.layout = QtGui.QVBoxLayout(self)
        self.layout.addWidget(self.button)
        self.layout.addWidget(self.listWidget)

        for itemNumber in range(5):
            item = QtGui.QListWidgetItem(self.listWidget)
            item.setText("Item {0}".format(itemNumber))
            self.listWidget.addItem(item)


    @QtCore.pyqtSlot()
    def on_button_clicked(self):
        enable = False if self.listWidget.isEnabled() else True

        self.listWidget.setEnabled(enable)

if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('myWindow')

    main = myWindow()
    main.show()

    sys.exit(app.exec_())
Godred answered 15/1, 2013 at 8:13 Comment(3)
Stylesheet is the way, but I think you could extend your answer similar to this example. :active, :!active and :disabled pseudo-states combined with :selected for ::item would practically provide any customization option. I didn't want to add an answer, since you already had one mentioning stylesheets :).Lindholm
@Lindholm Thanks for your suggestions! I added them to my answer :)Godred
Nice! Just what I was looking for, I wish the official docs for stylesheets were as helpful. I will add that while the background was consistent across states the text colour of the QListWidget's selected items changed from white with focus to black without focus. Easily solved by adding "color: white;" to each section of the stylesheet. Thanks!Schaab
S
2

The simplest approach is alter QPalette (if style sheet doesn't work for you).
Just set palette for QListView with values you want to alter (only).

Do something like that:

QPalette customPalette;
QPalette orginalPallete = listView->palette();
customPalette->setBrush(QPalette::Disabled, QPalette::Highlight,
                        orginalPallete.brush(QPalette::Active, QPalette::Highlight));
listView->setPalette(customPalette);

I recommend to read how palette property works (it merges values from parents and QApplication so you need set only thing you want to change).
You can also change this colors globally by changing palette for QApplication.

Sixtasixteen answered 15/1, 2013 at 11:7 Comment(0)
I
1

QItemDelegate can be used to provide custom display features. I hope it will help you. You can reimplement

virtual void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
Interdigitate answered 15/1, 2013 at 5:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.