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