PyQt Разные цвета в одной строке в поле со списком

Я разрабатываю пользовательский интерфейс с использованием PyQt, где один элемент в моем Qcombobox может иметь два или три слова, разделенных запятыми. Так, например, элемент 1 может быть "Text1, Text2, Text3", а элемент 2 будет "Text4, Text5".

Что я хочу сделать, так это задать несколько цветов фона для элементов, разделенных знаком ',' в itemText. Итак, в случае элемента 1 ('Text1, Text2, Text3') мне нужен цвет позади Text1, другой цвет позади Text2 и третий за Text3. Точно так же элемент 2 будет иметь 2 цвета фона.

Я думал об использовании формата rtf, но не мог найти способ придать несколько цветов одной строке элемента.

Спасибо вам за помощь.


person floyd1510    schedule 15.01.2014    source источник
comment
Чтобы изменить цвет фона слов в том же тексте, я думаю, вы должны использовать теги html. Но поскольку comboBox не будет интерпретировать теги, вам нужно создать делегат для отображения вашего текста. Этот делегат будет отвечать за интерпретацию тегов html.   -  person Frodon    schedule 17.01.2014


Ответы (1)


Один из способов сделать это — использовать QTextDocument для отображения форматированного текста. для элементов списка (через настраиваемый делегат), а также для преобразования форматированный текст обратно в обычный текст для текущего текста поля со списком (через его событие рисования).

Это позволит вам использовать 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())
person ekhumoro    schedule 18.01.2014