【问题标题】:Using multiple QStyledItemDelegate with stylesheets将多个 QStyledItemDelegate 与样式表一起使用
【发布时间】:2023-03-16 10:50:01
【问题描述】:

我正在使用双重调度创建一个样式化的 QTreeView 来解析数据项的特定委托,效果很好。我将 QStyledItemDelegate 中的委托子类化以利用样式表,使设计人员能够在代码之外设置 UI 样式。

不幸的是,我无法从 CSS 中处理不同的样式。如何选择和使用样式表中指定的项子控件样式?

我正在测试的 CSS:

QTreeView::item:selected {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #dddddd, stop: 1 #888888);
}
QTreeView::item:selected[role="title"] {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #fde7ef, stop: 1 #f1cbda);
}
QTreeView::item:selected[role="entry"] {
    background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1);
}

我的委托渲染类:

class VisitingDelegate(QtGui.QAbstractItemDelegate):
    def __init__(self, parent=None):
        super(VisitingDelegate,self).__init__(parent)
        roles = {}
        self.renderRoles = roles

        d = TitleDelegate(parent)
        d.setProperty("role", "title")
        roles['title'] = d

        d = EntryDelegate(parent)
        d.setProperty("role", "entry")
        roles['entry'] = d

    def delegateForIndex(self, mi):
        role = mi.model().data(mi, "renderRole")
        return self.renderRoles[role]

    def paint(self, painter, option, mi):
        dg = self.delegateForIndex(mi)
        return dg.paint(painter, option, mi)
    def sizeHint(self, option, mi):
        dg = self.delegateForIndex(mi)
        return dg.sizeHint(option, mi)

class TextDocumentDelegate(QtGui.QStyledItemDelegate):
    fmt = "<font color='%(color)s'>%(text)s</font)>"
    def paint(self, painter, option, mi):
        painter.save()

        opt = QtGui.QStyleOptionViewItemV4(option)
        self.initStyleOption(opt, mi)
        opt.text = ''

        style = opt.widget.style()
        style.drawControl(style.CE_ItemViewItem, opt, painter, opt.widget)

        textRect = style.subElementRect(style.SE_ItemViewItemText, opt, opt.widget);
        doc = self.asTextDoc(option, mi)
        painter.translate(textRect.topLeft())
        doc.drawContents(painter)

        painter.restore()

    def sizeHint(self, option, mi):
        doc = self.asTextDoc(option, mi)
        sz = doc.size()
        sz = QtCore.QSize(sz.width(), sz.height())
        return sz

    def asTextDoc(self, option, mi):
        info = {}
        info['text'] = mi.model().data(mi, Qt.DisplayRole)

        doc = QtGui.QTextDocument()
        doc.setDefaultFont(option.font)
        pal = option.palette
        if option.state & QtGui.QStyle.State_Selected:
            color = pal.color(pal.HighlightedText)
        else: color = pal.color(pal.Text)
        info['color'] = color.name()

        doc.setHtml(self.fmt % info)
        return doc

class EntryDelegate(TextDocumentDelegate):
    pass
class TitleDelegate(TextDocumentDelegate):
    fmt = "<h3><font color='%(color)s'>%(text)s</font)></h3>"

【问题讨论】:

  • 你确定这段代码真的被调用了吗?你如何设置代表?
  • 好吧,我宁愿覆盖 itemDelegate(QModelIndex),除非它没有标记为虚拟。相反,我使用setItemDelegate(VisitingDelegate()),模仿[使用 Python 和 Qt 进行快速 GUI 编程][1] 中的类似抽象。不幸的是,本书版本没有解决在代理中使用 CSS 的问题。 [1]:qtrac.eu/pyqtbook.html

标签: qt4 pyqt4


【解决方案1】:

不能这样选择不同的样式。用于选择样式表规则的属性取自 QWidget(在本例中为 QTreeView),而不是委托。委托不是小部件,也没有代表单个项目的小部件。您的示例可以通过添加从小部件获取样式的打印来显示这一点:

style = opt.widget.style()
print opt.widget

它将显示样式为 QTreeView 的小部件。由于两个代表的小部件相同,因此它不能具有两个值的角色设置。

即使样式表被写成看起来角色与项目相关联,但规则选择就像是这样写的:

QTreeView[role="title"]::item:selected

【讨论】:

    猜你喜欢
    • 2013-10-08
    • 2014-03-04
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    • 2021-10-03
    相关资源
    最近更新 更多