2014-01-15 72 views
3

我正在開發一個使用PyQt的UI,其中我的Qcombobox中的單個項目可以有兩個或三個單詞用逗號分隔。因此,例如項目1可以是'Text1,Text2,Text3',項目2將'Text4,Text5'。PyQt組合框中單行中的不同顏色

我想要做的是給項目文本中由','分隔的項目提供多種背景顏色。因此,在第1(「文本1,文本2,文本3」)的情況下,我需要背後文本1顏色,不同的一個背後文本2背後文本3第三個。同樣,項目2會有2種背景顏色。

我正在考慮使用rtf格式,但不能找出一種方法來給一個項目行多個顏色。

謝謝你的幫助。要做到這一點

+1

要改變同一文本中單詞的背景顏色,我認爲你應該使用html標籤。但由於comboBox不會解釋標籤,因此您必須創建一個委託才能顯示文本。這個代表將負責解釋html標籤。 – Frodon

回答

4

的一種方法是使用QTextDocument呈現富文本的組合框項目(通過自定義delegate),並以豐富的文本轉換回純文本的combo-的當前文本盒子(通過其paint event)。

這將允許您使用HTML的項目文本,就像這樣:

self.combo = RichTextCombo(self) 
    self.combo.addItem(""" 
     <span style="background-color: blue">Blue</span> 
     <span style="background-color: red">Red</span> 
     """) 

這裏的ComboBox類:

class RichTextCombo(QtGui.QComboBox): 
    def __init__(self, *args, **kwargs): 
     super(RichTextCombo, self).__init__(*args, **kwargs) 
     self._document = QtGui.QTextDocument(self) 
     self._delegate = RichTextDelegate(self) 
     self.setItemDelegate(self._delegate) 
     self.setSizeAdjustPolicy(
      QtGui.QComboBox.AdjustToMinimumContentsLength) 

    def paintEvent(self, event): 
     painter = QtGui.QStylePainter(self) 
     painter.setPen(self.palette().color(QtGui.QPalette.Text)) 
     options = QtGui.QStyleOptionComboBox() 
     self.initStyleOption(options) 
     self._document.setHtml(options.currentText) 
     options.currentText = self._document.toPlainText() 
     painter.drawComplexControl(QtGui.QStyle.CC_ComboBox, options) 
     painter.drawControl(QtGui.QStyle.CE_ComboBoxLabel, options) 

和這裏的自定義項目委託方:

class RichTextDelegate(QtGui.QStyledItemDelegate): 
    def __init__(self, *args, **kwargs): 
     super(RichTextDelegate, self).__init__(*args, **kwargs) 
     self._document = QtGui.QTextDocument(self) 

    def paint(self, painter, option, index): 
     options = QtGui.QStyleOptionViewItemV4(option) 
     self.initStyleOption(options, index) 
     if options.widget is not None: 
      style = options.widget.style() 
     else: 
      style = QtGui.QApplication.style() 
     self._document.setHtml(options.text) 
     options.text = '' 
     style.drawControl(QtGui.QStyle.CE_ItemViewItem, options, painter) 
     context = QtGui.QAbstractTextDocumentLayout.PaintContext() 
     if options.state & QtGui.QStyle.State_Selected: 
      context.palette.setColor(
       QtGui.QPalette.Text, options.palette.color(
        QtGui.QPalette.Active, QtGui.QPalette.HighlightedText)) 
     textRect = style.subElementRect(
      QtGui.QStyle.SE_ItemViewItemText, options) 
     painter.save() 
     painter.translate(textRect.topLeft()) 
     painter.setClipRect(textRect.translated(-textRect.topLeft())) 
     self._document.documentLayout().draw(painter, context) 
     painter.restore() 

    def sizeHint(self, option, index): 
     options = QtGui.QStyleOptionViewItemV4(option) 
     self.initStyleOption(options,index) 
     self._document.setHtml(options.text) 
     self._document.setTextWidth(options.rect.width()) 
     return QtCore.QSize(self._document.idealWidth(), 
          self._document.size().height())