【问题标题】:How do I set item delegates for multiple columns in a model that is processed by a proxy model?如何为代理模型处理的模型中的多个列设置项目委托?
【发布时间】:2018-03-26 13:43:38
【问题描述】:

我这样设置我的项目代表:

COMBOBOX_ITEMS_FRUITS = ['Apple', 'Banana']
COMBOBOX_ITEMS_COLORS = ['Red', 'Green', 'Blue']

self.treeview.setItemDelegateForColumn(COLUMN_A, ComboBoxDelegate(COMBOBOX_ITEMS_FRUITS))
self.treeview.setItemDelegateForColumn(COLUMN_B, ComboBoxDelegate(COMBOBOX_ITEMS_COLORS))

将模型设置为代理模型的源模型后,我的应用崩溃但没有抛出错误:

self.model_source = treeview_model
self.sf_proxy_model.setSourceModel(self.model_source)

使用sortfilterproxymodel处理源模型的时候好像只能用一个setItemDelegateForColumn

ComboBoxDelegate定义如下:

class ComboBoxDelegate(QStyledItemDelegate):
    def __init__(self, items):
        super(ComboBoxDelegate, self).__init__()

        self.items = items

    def createEditor(self, parent, option, index):
        editor = QComboBox(parent)
        editor.setAutoFillBackground(True)

        for item in self.items:
            editor.addItem(item)

        return editor

    def setEditorData(self, editor, index):
        current_index = editor.findText(index.model().data(index), Qt.MatchExactly)
        editor.setCurrentIndex(current_index)

    def setModelData(self, editor, model, index):
        item_index = model.mapToSource(index)
        item = model.sourceModel().item(item_index.row(), 0)

        if index.parent().row() == -1 and item.hasChildren():
            for row in range(item.rowCount()):
                child = item.child(row, 3)
                child.setText(editor.currentText())

        model.setData(index, editor.currentText())

    def updateEditorGeometry(self, editor, option, index):
        editor.setGeometry(option.rect)

【问题讨论】:

    标签: python pyqt pyqt5 qtreeview qstyleditemdelegate


    【解决方案1】:

    treeview 不获取委托的所有权,因此您必须自己保留对它的引用(否则它将被 python 垃圾收集):

        self.delegate1 = ComboBoxDelegate(COMBOBOX_ITEMS_FRUITS)
        self.delegate2 = ComboBoxDelegate(COMBOBOX_ITEMS_COLORS)
        self.view.setItemDelegateForColumn(COLUMN_A, self.delegate1)
        self.view.setItemDelegateForColumn(COLUMN_B, self.delegate2)
    

    【讨论】:

    • here 是我所知道的关于 GC 问题的唯一文档。如果有人有更好的资源,我很想知道。我发现这个问题不一致; QtLayout(self) 工作得很好。
    • @hansonap 没有不一致,也没有 GC 问题。 Qt documentation 总是非常清楚何时需要了解对象所有权。
    • hmm...这是我的想法:1. 是的,文档确实声明“QAbstractItemView 不获取委托的所有权” 2. 不获取所有权(我相信)对于 c++ 来说不是问题因此是一个 PyQt 问题 3。鉴于 2。PyQt 最好有更好的文档;也许“如果 Qt 文档状态 \"QAbstractItemView 不获取委托的所有权\",请继续参考。我联系了 PyQt,希望为他们的文档做出贡献,希望能提供一些关于这个主题的额外信息。
    • @hansonap 这绝对与 C++ 相关,这正是 Qt 文档特别提到它的原因。但是,这肯定不是 PyQt 问题——它只是正常的 Python 行为。如果您不在 Python 中保留对对象的引用,它们将被垃圾收集(最终)。这与 PyQt per se 无关——它对所有 Python 应用程序都很常见。这里唯一的“问题”是 Qt 特有的:它的 API 是为 C++ 设计的,可以理解的是,它没有考虑可能包装其库的其他语言。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2011-01-29
    • 2017-11-08
    • 2021-06-11
    • 2022-12-05
    • 1970-01-01
    相关资源
    最近更新 更多