alphanumeric alphanumeric - 2 months ago 59
Python Question

PyQt: How to customize ComboBox Items display

Is it possible to create a ComboBox item first, then set its display properties (such as item's background color, icon, font color, font size and etc and only then to add it to ComboBox using Comobobox's .addItem() method? As it is now I am stuck using:

myCombobox = QtGui.QComboBox
for i in range(10):
myCombobox.addItem(str(i))


Needless to say this approach leaves little space for customization of the individual ComboBox's items display properties. What I would like is something like this:

myCombobox = QtGui.QComboBox
for i in range(10):
item = comboboxItem()
item.setColor(allBlueAndShiny)
font = QtGui.QFont()
font.setPointSize(10)
item.setFont(font)

# Only after item was set with all display properties it is added:
myCombobox.addItem(str(i))


Edited later

Here is a working example of QCombobox's customized items. Thanks Ekhumoro!




from PyQt4 import QtGui, QtCore

def main():
app = QtGui.QApplication(sys.argv)
window = QtGui.QWidget()
main_layout = QtGui.QVBoxLayout()
# QComboBox
combo = QtGui.QComboBox()
model = combo.model()
for row in range(10):
item = QtGui.QStandardItem(str(row))
item.setForeground(QtGui.QColor('red'))
font = item.font()
font.setPointSize(10)
item.setFont(font)
model.appendRow(item)
main_layout.addWidget(combo)

ok_button = QtGui.QPushButton("OK")
ok_button.clicked.connect(OK)
main_layout.addWidget(ok_button)

main_layout.addStretch(1)
window.setLayout(main_layout)
window.show()
sys.exit(app.exec_())

def OK(self):
print 'OK'

if __name__ == '__main__':
main()

Answer

By default, QComboBox uses a QStandardItemModel, so the QStandardItem methods can be used to change the various display properties:

combo = QtGui.ComboBox()
model = combo.model()
for row in range(10):
    item = QtGui.QStandardItem(str(index))
    item.setForeground(QtGui.QColor('red'))
    font = item.font()
    font.setPointSize(10)
    item.setFont(font)
    model.addRow(item)

PS:

If you want to reset one of the item properties, set it to None, like this:

    item = self.combo.model().item(row)
    item.setData(None, QtCore.Qt.ForegroundRole)