首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在QComboBox中显示树模型的分支

在QComboBox中显示树模型的分支
EN

Stack Overflow用户
提问于 2021-08-03 14:56:32
回答 1查看 55关注 0票数 0

免责声明:我为这个话题找到了不同的类似答案,但我找不到解决我的问题的答案。

我有下面的源代码模型结构,它由一个单列的无头QTreeView显示

代码语言:javascript
复制
- Cat 1
|-- Cat1_El1
|-- ...
|-- Cat1_ElL
...
- Cat N
|-- CatN_El1
|-- ...
|-- CatN_ElM

视图和源模型工作得很好。每个低级项目都是由用户动态创建的,而类别则是硬编码的。

现在,核心问题如下:基于某个条件,我可以通过实例化的代理模型的额外属性轻松管理,我希望在QComboBox中显示特定类别的所有项。我想过重新实现QAbstractProxyModel,但我面临着一些麻烦,无法理解如何重新实现Qt Doc声明的mapFromSourcemapToSource这两个方法。我想出来的东西如下所示。我所有的怀疑和推断都被报告为评论,因为我认为它更清晰。注意,我是用Python语言编写代码,使用PyQt5,但实际上我更感兴趣的是如何重新实现代理的概念,而不是代码本身(因此,C++代码也可以很好地工作)

代码语言:javascript
复制
class GWModulesComboProxy(QIdentityProxyModel):
    # This re-implements the basic proxy structure
    def __init__(self, moduleType : CategoriesType, parent: Optional[QObject]) -> None:
        # `CategoriesType` --> See later `ComboProxyCatN`
        self.moduleType = moduleType
        super().__init__(parent)

    def index(self, row: int, column: int, parent: QModelIndex) -> QModelIndex:
    #   Based upon the crash of the model when clicking on the combobox, I'm inferring that I should re-implementing 
    #   this method and call, FROM it, the `mapToSource`. But I can't figure out how
        pass

    def mapFromSource(self, sourceIndex: QModelIndex) -> QModelIndex:
        if not sourceIndex.isValid():
            return QModelIndex()
        
        # If the node is a root node (i.e. a Cathegory itself), it will never show up into the ComboBox
        if not sourceIndex.parent().isValid():
            return QModelIndex()
        
        # Into the source model, the root nodes are ordered against the IntEnum CategoriesType --> See later `ComboProxyCatN`
        if sourceIndex.parent().row() == self.moduleType:
            return sourceIndex
        
        return QModelIndex()

    def mapToSource(self, proxyIndex: QModelIndex) -> QModelIndex:
        if not proxyIndex.isValid():
            return QModelIndex()

        parent = self.sourceModel().index(self.moduleType, 1, QModelIndex()) 
        return self.sourceModel().index(proxyIndex.row(), proxyIndex.column(), parent)


        
    def data(self, proxyIndex: QModelIndex, role: int) -> Any:
    #   I was guessing that re-implementing `data` was meaningless since the data should be already taken from the source
    #       by means of the mapper methods. Am I correct?
        pass

    def columnCount(self, parent: QModelIndex) -> int:
        return 1

class ComboProxyCatN(ComboProxy):
    # Just an example how to manage the specific Category N
    def __init__(self, parent: Optional[QObject]) -> None:
        # CategoriesType is an IntEnum that stores the different cathegories
        super().__init__(CategoriesType.CatN, parent)
EN

回答 1

Stack Overflow用户

发布于 2021-08-03 15:18:22

要显示树的分支,不需要使用代理模型,而是必须通过QComboBox的setRootModelIndex()方法来指示根。

下面的示例显示了类别"Cat 5“的分支:

代码语言:javascript
复制
import random

from PyQt5 import QtCore, QtGui, QtWidgets


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    model = QtGui.QStandardItemModel()

    for i in range(1, 10):
        root_item = QtGui.QStandardItem(f"Cat {i}")
        model.appendRow(root_item)
        for j in range(1, random.randrange(5, 10)):
            child_item = QtGui.QStandardItem(f"Cat{i}_El{j}")
            root_item.appendRow(child_item)

    view = QtWidgets.QTreeView()
    view.setModel(model)
    view.expandAll()

    category = "Cat 5"

    root_index = QtCore.QModelIndex()
    indexes = model.match(
        model.index(0, 0), QtCore.Qt.DisplayRole, category, flags=QtCore.Qt.MatchExactly
    )
    if indexes:
        root_index = indexes[0]

    # or fifth row
    # root_index = model.index(4, 0)

    combobox = QtWidgets.QComboBox()
    combobox.setModel(model)
    combobox.setRootModelIndex(root_index)
    combobox.setCurrentIndex(0)

    widget = QtWidgets.QWidget()
    lay = QtWidgets.QVBoxLayout(widget)
    lay.addWidget(view)
    lay.addWidget(combobox)
    widget.resize(640, 480)
    widget.show()

    sys.exit(app.exec_())
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68638358

复制
相关文章

相似问题

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