首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >分别设置QComboBox菜单项的样式( PyQt5 )

分别设置QComboBox菜单项的样式( PyQt5 )
EN

Stack Overflow用户
提问于 2020-04-20 06:11:11
回答 1查看 870关注 0票数 1

我试图对QComboBox菜单中的项目进行单独的样式设计。在QAbstractItemView中,它通过Qt样式表示例设置菜单的样式。

代码语言:javascript
运行
复制
QComboBox QAbstractItemView {
    border: 2px solid darkgray;
    selection-background-color: lightgray;
}

它提供了对菜单的常规控制,但除了对选定项的轻微控制外,不对单个项进行控制。另一种解决方案是使用QAbstractItemView::item,这对我来说是行不通的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-20 12:52:13

似乎您有一个XY问题,因为正如您指出的那样,您的目标是“绘制下拉菜单”(非常通用),但是您询问可能的解决方案(另一个问题)的错误,这并不一定对您有帮助。

考虑到以上所述,我将解释错误的原因和可能的解决方案(显然,我做了许多假设)。

主要错误是,这段代码用于PyQt4,您可能正在使用PyQt5,在PyQt4中,data()方法返回必须转换为python对象的QVariant,因此使用isValid()和toPyObject(),但在pyqt5中不再需要。另一个错误是,UserRole值将为None,因为您在创建该项时没有分配任何值(这可能是由于另一个问题中的遗漏造成的)。

考虑到上述情况,一个可能的解决方案(兼容PyQt4和PyQt5)是:

代码语言:javascript
运行
复制
class LineStyleDelegate(QItemDelegate):
    def paint(self, painter, option, index):
        data = index.data(Qt.UserRole)
        if hasattr(data, "toPyObject"):
            data = data.toPyObject()
        if data is not None:
            painter.save()
            rect = option.rect
            rect.adjust(+5, 0, -5, 0)
            pen = QPen()
            pen.setColor(Qt.black)
            pen.setWidth(3)
            pen.setStyle(data)
            painter.setPen(pen)
            middle = (rect.bottom() + rect.top()) / 2
            painter.drawLine(rect.left(), middle, rect.right(), middle)
            painter.restore()
        else:
            QItemDelegate.paint(self, painter, option, index)
代码语言:javascript
运行
复制
        self.searchEdit = QComboBox(sef.searchContent)
        for text, style in (
            ("Item 1", Qt.SolidLine),
            ("Item 2", Qt.DotLine),
            ("Item 3", Qt.DashDotDotLine),
        ):
            self.searchEdit.addItem(text, style)
        self.delegate = LineStyleDelegate(self.searchEdit)
        self.searchEdit.setItemDelegate(self.delegate)
        self.searchEdit.setMinimumWidth(500)
        self.searchEdit.setEditable(True)

更新:

通过对问题的修正,验证了OP存在XY问题。若要修改QComboBox项的绘制,必须使用委托: QItemDelegate或QStyledItemDelegate。我更喜欢使用第二个,因为它使用QStyle,也就是说,设计将尊重图形用户界面的风格。若要设置每个项的颜色,请使用QStyleOptionViewItem的QStyleOptionViewItem属性,而对于边框绘制,则必须重写QStyleOptionViewItem()方法:

代码语言:javascript
运行
复制
import random

from PyQt5 import QtCore, QtGui, QtWidgets


class CustomStyleDelegate(QtWidgets.QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super(CustomStyleDelegate, self).initStyleOption(option, index)
        random_color = QtGui.QColor(*random.sample(range(255), 3))
        option.backgroundBrush = random_color

    def paint(self, painter, option, index):
        super(CustomStyleDelegate, self).paint(painter, option, index)
        margins = 2
        border_color = QtGui.QColor(*random.sample(range(255), 3))
        painter.save()
        pen = QtGui.QPen()
        pen.setColor(border_color)
        pen.setWidth(margins)
        painter.setPen(pen)
        r = QtCore.QRect(option.rect).adjusted(0, 0, -margins, -margins)
        painter.drawRect(r)
        painter.restore()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QComboBox()
    w.addItems(["Item 1", "Item 2", "Item 3"])
    delegate = CustomStyleDelegate(w)
    w.setItemDelegate(delegate)
    w.show()
    sys.exit(app.exec_())
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61316109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档