PyQt组合框中的一行中的不同颜色 [英] PyQt Different colors in a single row in a combobox

查看:249
本文介绍了PyQt组合框中的一行中的不同颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用PyQt开发UI,其中Qcombobox中的单个项目可以用逗号分隔两个或三个单词。因此,例如,项目1可以是 Text1,Text2,Text3 ,项目2将是 Text4,Text5



我想做的是给itemText中用','分隔的项目赋予多种背景颜色。因此,在第1项的情况下(' Text1,Text2,Text3 '),我需要在 Text1 后面加上一种颜色,在 Text2 后面加上另一种颜色在 Text3 之后排第三。同样,第2项将具有2种背景颜色。



我当时在考虑使用rtf格式,但无法找到一种为一行提供多种颜色的方法。 / p>

谢谢您的帮助。

解决方案

做到这一点的一种方法是使用 QTextDocument 来呈现组合框项目的富文本格式(通过自定义代理),并将富文本格式转换为组合框当前文本的纯文本格式(通过其绘制事件)。



这将允许您将html用于项目文本,例如:

  self.combo = RichTextCombo(self)
self.combo.addItem(
< span style = background- C olor:蓝色>蓝色/ 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_Co mboBox,选项)
painter.drawControl(QtGui.QStyle.CE_ComboBoxLabel,选项)

这是自定义项目委托:

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

def paint(自己,画家,选项,索引):
options = QtGui.QStyleOptionViewItemV4(option)
self.initStyleOption(options,index)
如果options.widget为不无:
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.Pain tContext()
如果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,选项)
painter.save()
painter.translate(textRect.topLeft())
画家。 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())
返回QtCore.QSize(self._document.idealWidth(),
self._document.size()。height())


I'm developing a UI using PyQt where a single item in my Qcombobox can have two or three words separated by commas. So for eg item 1 can be 'Text1, Text2, Text3' and item 2 will be 'Text4, Text5'.

What I want to do is give multiple background colors to the items separated by the ',' in the itemText. So, in case of item 1 ('Text1, Text2, Text3') I would need a color behind Text1, a different one behind Text2 and a third one behind Text3. Similarly, item 2 would have 2 background colors.

I was thinking of using rtf format, but could not figure out a way to give multiple colors to one item row.

Thank you for the help.

解决方案

One way to do this is to use a QTextDocument to render rich-text for combobox items (via a custom delegate), and also to convert the rich-text back to plain-text for the current text of the combo-box (via its paint event).

This would allow you to use html for the item text, like so:

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

Here's the combobox class:

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)

and here's the custom item-delegate:

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())

这篇关于PyQt组合框中的一行中的不同颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆