QComboBox list popup display in Fusion style

100 Views Asked by At

I am using PyQt5. I want to know how to make my QComboBox open with ±10 items instead of the full screen. This only happens with the fusion style applied. Is there any way I can make this behave with a small drop down instead? I have tried to use setMaxVisibleItems(5), but it didn't make a difference.

Here is what it is looking like now:

example

1

There are 1 best solutions below

4
ekhumoro On BEST ANSWER

As pointed out in QTBUG-89037, there's an undocumented stylesheet property that can be used to change the behaviour of the popup:

setStyleSheet('QComboBox {combobox-popup: 0}')

A value of 0 will show the normal scrollable list-view with a maximum number of visible items, whilst a value of 1 shows the humungous menu.

However, in some circumstances, setting a stylesheet may have undesirable side-effects, since it could potentially interfere with the default behaviour of QStyle. So an alternative solution might be to use a proxy-style, and reimplement its styleHint method so that it returns either 0 or 1 for QStyle.SH_ComboBox_Popup.

Both of these solutions work with both Qt5 and Qt6, and will also work for styles such as "cleanlooks" as well as "fusion".

Here's a simple demo that implements both solutions:

screenshot

from PyQt5 import QtWidgets
# from PyQt6 import QtWidgets

class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.combo = QtWidgets.QComboBox()
        self.combo.addItems(f'Item-{i:02}' for i in range(1, 50))
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.combo)

class ProxyStyle(QtWidgets.QProxyStyle):
    def styleHint(self, hint, option, widget, data):
        if hint == QtWidgets.QStyle.StyleHint.SH_ComboBox_Popup:
            return 0
        return super().styleHint(hint, option, widget, data)

if __name__ == '__main__':

    app = QtWidgets.QApplication(['Combo Test'])

    app.setStyle('fusion')
#     app.setStyle('cleanlooks')
#     style = ProxyStyle(app.style())
#     app.setStyle(style)

    app.setStyleSheet('QComboBox {combobox-popup: 0}')

    window = Window()
    window.setGeometry(600, 100, 200, 75)
    window.show()
    app.exec()