2014-01-15 4 views
3

내 Qcombobox의 단일 항목에 쉼표로 구분 된 두 단어 또는 세 단어가있을 수있는 PyQt를 사용하여 UI를 개발하고 있습니다. 따라서 항목 1은 '텍스트 1, 텍스트 2, 텍스트 3'이고 항목 2는 '텍스트 4, 텍스트 5'이 될 수 있습니다.PyQt 콤보 박스의 한 줄에 다른 색상이 있습니다.

내가 원하는 것은 itemText에서 ','로 구분 된 항목에 여러 배경색을주는 것입니다. 그래서, 항목 1 ('텍스트 1, 텍스트 2, 텍스트 3')의 경우에 나는 텍스트 1 뒤에 색상, 텍스트 2 뒤에 다른 하나 텍스트 3 뒤에 세 번째가 필요합니다. 마찬가지로 항목 2는 2 개의 배경색을가집니다.

rtf 형식을 사용하려고 생각했지만 한 항목 행에 여러 색상을 지정할 수있는 방법을 찾지 못했습니다.

도움 주셔서 감사합니다. 이 작업을 수행하는

+1

동일한 텍스트의 단어 배경색을 변경하려면 html 태그를 사용해야합니다. 그러나 comboBox는 태그를 해석하지 않으므로 텍스트를 표시 할 대리자를 만들어야합니다. 이 대리인은 html 태그를 해석 할 책임이 있습니다. – Frodon

답변

4

한 가지 방법은 combo-의 현재 텍스트를 일반 텍스트로 다시 서식있는 텍스트를 변환 할 수 있습니다 (사용자 정의 delegate를 통해) 콤보 항목에 대한 서식있는 텍스트를 렌더링하는 QTextDocument를 사용하는 것입니다 상자 (해당 paint event 통해).

이것은 당신과 같이 항목 텍스트에 HTML을 사용할 수 있도록 것 : 여기

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

는 콤보 클래스의 :

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()) 
관련 문제