<div dir="ltr">My question was badly worded.  The PyQt4/PySide documentation for QComboBox does show a setStyleSheet method for the top-level widget, and this works just fine, but it looks as though there is nothing comparable for the individual combobox options.  I've written a class that manipulates the foreround and background colors of individual combobox options, but it does not work perfectly, and it is also surprising that so much code is needed to accomplish so little.  There must be a better way.  Any advice will be appreciated.<div><br></div><div>Phillip</div><div><br></div><div><div>class UserCombo(UserWidget):</div><div>   """</div><div>   This class generates a label and a ComboBox (dropdown list) laid out</div><div>   horizontally.  The ComboBox can optionally be made editable.  Note:</div><div><br></div><div>   - With a ListBox, which is added via the `add_list` method, options are</div><div>   visible at all times (unless scrolled off the top or bottom of the window),</div><div>   and it may be possible-depending on the value of the multiselect argument--</div><div>   for the user to select more than one option.</div><div><br></div><div>   - With a ComboBox, which is added via the `add_combo` method, the list of</div><div>   options is visible only when one activates the widget by clicking on it, and</div><div>   one cannot select more than one option.</div><div><br></div><div>   Because of inconsistencies between Qt widget interfaces, this class works</div><div>   somewhat differently from the other user dialog widgets.  In particular, one</div><div>   cannot apply html/css stylesheets to the individual options.  The separate</div><div>   arguments `font_size`, `background_colors`, and `foreground_colors` do,</div><div>   however, provide some control over the appearance of the individual options.</div><div><br></div><div>   References:</div><div><br></div><div>   <a href="http://stackoverflow.com/questions/22887496/pyqt-how-to-customize-combobox-items-display">http://stackoverflow.com/questions/22887496/pyqt-how-to-customize-combobox-items-display</a></div><div>   """</div><div><br></div><div>   def __init__(self, name, label='', options=[], default=None, editable=False,</div><div>     label_style_sheet=None, field_style_sheet='font-size:12pt; color:#0000CC',</div><div>     font_size='12pt',</div><div>     background_colors=None, foreground_colors=None, validator=None):</div><div>      """</div><div>      `name` is a string that identifies this field when dialog inputs are</div><div>      returned.</div><div><br></div><div>      `label` is a string containing identifying text to be displayed above the</div><div>      group of radio buttons.</div><div><br></div><div>      `options` is a non-empty list or tuple of strings.  Each string appears as</div><div>      an item in the drop-down list.</div><div><br></div><div>      `default`--an optional input--indicates the default selection.  If a</div><div>      default is provided, it must match one of the strings in `options`.</div><div><br></div><div>      `editable`--MISSING TEXT AT THIS POINT!</div><div><br></div><div>      `label_style_sheet`--an optional input--is a string containing an html</div><div>      style sheet to be applied to the label text (prompt).  The default is</div><div>      'font-size:12pt; color:#000000', which causes the label to be displayed in</div><div>      a 12-point black font.</div><div><br></div><div>      `field_style_sheet`--an optional argument--is a string containing an html</div><div>      style sheet to be applied to the top-level widget.  The default is</div><div>      'font-size:12pt;color:#0000CC'.</div><div><br></div><div>      `font_size`--an optional argument--is a string specifying the font size</div><div>      for option text.  The default is '12pt'.</div><div><br></div><div>      `background_colors` and `foreground_colors`--optional arguments--are each</div><div>      either a single string or a list of strings.  If a list is provided, its</div><div>      length must match that of `options`.  Each string is an html color name</div><div>      that sets the background or foreground (text) color, respectively, of the</div><div>      corresponding option, or of all options if only a single string (not</div><div>      enclosed in a list) is provided.  Both defaults are `None`, indicating</div><div>      that widget defaults apply.</div><div>      """</div><div>      super(UserCombo, self).__init__(name, validator=validator)</div><div>      layout= QGridLayout()</div><div>      self.setLayout(layout)</div><div><br></div><div>      self.label= QLabel(label)</div><div>      if label_style_sheet is not None:</div><div>         self.label.setStyleSheet(label_style_sheet)</div><div><br></div><div>      self.field= QComboBox()</div><div>      self.field.setEditable(editable)</div><div>      self.field.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)</div><div>      self.label.setBuddy(self.field)</div><div><br></div><div>      # Save calling arguments for later use:</div><div>      self.font_size= font_size</div><div>      self.background_colors= copy.deepcopy(background_colors)</div><div>      self.foreground_colors= copy.deepcopy(foreground_colors)</div><div><br></div><div>      # Creating a 'model' allows us to add instances of QStandardItem with</div><div>      # individual formatting:</div><div>      self.model= self.field.model()</div><div>      self.items= []</div><div><br></div><div>      for i_option, option in enumerate(options):</div><div>         item= QStandardItem(option)</div><div>         self.model.appendRow(item)</div><div>         self.items.append(item)</div><div>         self.index_changed(i_option)</div><div><br></div><div>      self.field.setStyleSheet(field_style_sheet)</div><div><br></div><div>      # Connect field to method that will be invoked whenever the user makes a</div><div>      # new selection:</div><div>      self.field.currentIndexChanged.connect(self.index_changed)</div><div><br></div><div>      layout.addWidget(self.label, 0, 0)</div><div>      layout.addWidget(self.field, 0, 1)</div><div>      layout.addWidget(self.errorLabel, 1, 1)</div><div><br></div><div>      # The editTextChanged event is not sent when the box is not editable.  We</div><div>      # need to use currentIndexChanged in that case.</div><div>      if editable:</div><div>         self.field.editTextChanged.connect(self.field_updated_handler)</div><div>      else:</div><div>         self.field.currentIndexChanged.connect(self.field_updated_handler)</div><div><br></div><div>      self.value= default</div><div><br></div><div><br></div><div>   def get_value(self):</div><div>      return self.field.currentText().encode('ascii', 'replace')</div><div><br></div><div><br></div><div>   def set_value(self, newval):</div><div>      # If the new value is one of the items in the list, select it.</div><div>      idx= self.field.findText(newval)</div><div>      if idx >= 0:</div><div>         self.field.setCurrentIndex(idx)</div><div>      elif self.field.isEditable():</div><div>         # If the new value is not in the list, only set it if</div><div>         # the field is editable, otherwise do nothing.</div><div>         self.field.setEditText(newval)</div><div><br></div><div><br></div><div>   def index_changed(self, i_option):</div><div>      """</div><div>      This method gets called when the user selects an item from the list.  It</div><div>      transfers color attributes from the selected item to the top-level widget.</div><div>      """</div><div><br></div><div>      item= self.items[i_option]</div><div><br></div><div>      bg= self.background_colors</div><div>      if bg is not None:</div><div>         if isinstance(bg, list):</div><div><br></div><div>            # There is a separate background style for each list item:</div><div>            bg= bg[i_option]</div><div><br></div><div>         item.setBackground(QColor(bg))</div><div><br></div><div>      fg= self.foreground_colors</div><div>      if fg is not None:</div><div>         if isinstance(fg, list):</div><div><br></div><div>            # There is a separate foreground style for each list item:</div><div>            fg= fg[i_option]</div><div><br></div><div>         item.setForeground(QColor(fg))</div><div><br></div><div>      # Set field stylesheet to match the most recent selection:</div><div>      field_style_sheet= 'font-size:{fs}; ' \</div><div>        'selection-background-color:{bg}; background-color:{bg}; color:{fg}' \</div><div>        .format(fs=self.font_size, bg=bg, fg=fg)</div><div>      self.field.setStyleSheet(field_style_sheet)</div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Apr 7, 2016 at 3:37 PM, Dave Gradwell <span dir="ltr"><<a href="mailto:davegradwell@yahoo.co.uk" target="_blank">davegradwell@yahoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Phillip,<br>
<span class=""><br>
> Worse yet, the API documentation does not mention a setStyleSheet method<br>
</span>QComboBox inherits setStyleSheet() from QWidget (where it may be better documented) so this should work:<br>
QtWidgets.QComboBox(parent).setStyleSheet("color:red;”)<br>
<br>
You may be able to style individual items by manipulating the Painter:<br>
<a href="http://stackoverflow.com/questions/516032/how-to-make-qcombobox-painting-item-delegate-for-its-current-item-qt-4" rel="noreferrer" target="_blank">http://stackoverflow.com/questions/516032/how-to-make-qcombobox-painting-item-delegate-for-its-current-item-qt-4</a><br>
A bit lower-level, but helped me achieve something similar when I needed to go beyond style-sheeting..<br>
<br>
Best, Dave.<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
> On 7 Apr 2016, at 21:58, Phillip Feldman <<a href="mailto:phillip.m.feldman@gmail.com">phillip.m.feldman@gmail.com</a>> wrote:<br>
><br>
> In Qt4 (or at least in PyQt4), it was possible to set a stylesheet for a QComboBox, but not possible to set styles on individual options/items in a QComboBox.  I was hoping that this would be addressed in Qt5, but it hasn't.  Worse yet, the API documentation does not mention a setStyleSheet method, so it looks as though the ability to set a stylesheet for the top-level widget has been removed.  I hope that I'm wrong on both of these points.<br>
><br>
> Phillip<br>
<br>
</div></div></blockquote></div><br></div>