6

Is it possible to create a combo-box item first, then set its display properties (such as background-color, icon, font-color, font-size, etc) and only then add it to the combo-box using QComoboBox.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 combo-box item's 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()
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
alphanumeric
  • 17,967
  • 64
  • 244
  • 392

1 Answers1

9

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

combo = QComboBox()
model = combo.model()
for row in range(10):
    item = QStandardItem(str(row))
    item.setForeground(QColor('red'))
    font = item.font()
    font.setPointSize(10)
    item.setFont(font)
    model.appendRow(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, Qt.ForegroundRole)
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • How do we reset an item's foreground color to a default "no color"? ...after the item was already set item.setForeground(QtGui.QColor('red')) there is a need to switch its display from color to default and vise versa... – alphanumeric Apr 07 '14 at 22:41
  • @Sputnix. See my updated answer. Also: I just realized that `QComboBox` already uses a `QStandardItemModel`, so I've simplified my example accordingly. – ekhumoro Apr 07 '14 at 23:08
  • Thanks! I found that to reset an item's color I can just set it to (QtGui.QColor('black')). The items only show their colors when you click on Combobox to show all items list. But when the combobox is closed the item shows no color (just regular color). Is there any way to "force" item show its color even when ComoboBox is "folded"? – alphanumeric Apr 07 '14 at 23:22
  • @Sputnix. Resetting the foreground to "black" is a bug, because not all color-schemes will have that color as the default (a dark color-scheme would have a contrasting light color for the default). As for the other issue: I think that goes beyond the scope of the current question, so please start a new one. – ekhumoro Apr 07 '14 at 23:37
  • @TodStoychev. Thanks - it was just a minor typo that was copied from the OPs original code example (which has now been corrected). Please suggest an edit for issues like this, because not everyone reads all the comments. – ekhumoro Feb 05 '17 at 18:14