How do I achieve consistent highlighting of QListW

2019-03-27 17:28发布

问题:

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.

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.

回答1:

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_())


回答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.



回答3:

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