代码之家  ›  专栏  ›  技术社区  ›  stowaway

具有多个标头的QStandardItemModel-将QTreeView标头与模型解耦

  •  1
  • stowaway  · 技术社区  · 8 年前

    我有一个QStandardItemModel,它在不同的视图中需要不同的水平标题标签。

    我很难找到有关如何以这种方式将QTreeView的头与模型解耦的信息。这可能吗?

    请参见下面的简单代码示例。


    在本例中,我们有ItemTypeA,它是我们的顶级项,其横轴表示属性“Name | interpolon | Normalize”。

    ItemTypeA(ItemTypeB)的子项在横轴上有表示“Name | Multiply”的项

    TreeViewA显示所有内容,TreeViewB仅显示所选顶级项的子项(本例中未实现选择连接)。

    from PySide.QtGui import *
    from PySide.QtCore import *
    
    class MyModel(QStandardItemModel):
    
        def __init__(self):
            super(MyModel, self).__init__()
            iroot = self.invisibleRootItem()
    
            self.setHorizontalHeaderLabels(['Name', 'Interpolation', 'Normalize'])
    
        def newTopLevelItem(self, name = 'myTopLevelItem'):
            item = ItemTypeA(name)
            root_item = self.invisibleRootItem()
            root_item.appendRow([item]+item.settingItems())
            return item
    
    
    class ItemTypeA(QStandardItem):
        def __init__(self, *args, **kwargs):
            super(ItemTypeA, self).__init__(*args, **kwargs)
    
            self.s_interpolation =QStandardItem('0')
            self.s_normalize = QStandardItem('False')
    
        def settingItems(self):
            return [
                self.s_interpolation,
                self.s_normalize
            ]
            
        def newChildItem(self, name = 'newChildItem'):
            childItem = ItemTypeB( name )
            self.appendRow( [childItem]+childItem.settingItems() )
    
    
    class ItemTypeB(QStandardItem):
        def __init__(self, *args, **kwargs):
            super(ItemTypeB, self).__init__(*args, **kwargs)
            
            self.s_multiply = QStandardItem('1.0')
    
        def settingItems(self):
            return [
                self.s_multiply,
            ]
            
    
    class TreeViewA(QTreeView):
        '''
        THIS VIEW Needs the Headers:
            Item Name | Interpolation | Normalize
        '''
        def __init__(self):
            super(TreeViewA, self).__init__()
            model = MyModel()
            self.setModel(model)
            
            newItem = model.newTopLevelItem()
            newItem.newChildItem()
    
    class TreeViewB(QTreeView):
        '''
        THIS VIEW Needs the Headers:
            Item Name | Multiply
        '''
        def __init__(self, sourceView):
            super(TreeViewB, self).__init__()
            model = sourceView.model()
            self.setModel(model)
            self.setRootIndex(model.index(0,0))
            
    
    class MyWidget(QWidget):
        
        def __init__(self):
            super(MyWidget, self).__init__()
            layout = QHBoxLayout()
            viewA = TreeViewA()
            viewB = TreeViewB(viewA)
            layout.addWidget(viewA)
            layout.addWidget(viewB)
            self.setLayout(layout)
    
    widget = MyWidget()
    widget.show()
    

    有什么想法?

    1 回复  |  直到 5 年前
        1
  •  2
  •   eyllanesc    8 年前

    这些情况的解决方案是使用QIdentialProxy模型,但PySide和PySide中不存在此类,因此我们必须使用类似的类,如QSortFilterProxy模型,并覆盖headerData方法。

    ...
    
    class HeaderProxyModel(QSortFilterProxyModel):
        def __init__(self, *args, **kwargs):
            QSortFilterProxyModel.__init__(self, *args, **kwargs)
            self.labels = []
        def setHeaderLabels(self, labels):
            self.labels = labels
        def headerData(self, section,orientation, role = Qt.DisplayRole):
            if orientation == Qt.Horizontal and 0 <= section < self.columnCount() and role==Qt.DisplayRole and section < len(self.labels) :
                return self.labels[section]
            return QSortFilterProxyModel.headerData(self, section, orientation, role)
    
    class TreeViewB(QTreeView):
        '''
        THIS VIEW Needs the Headers:
            Item Name | Multiply
        '''
        def __init__(self, sourceView):
            super(TreeViewB, self).__init__()
            model = sourceView.model()
            proxy = HeaderProxyModel()
            proxy.setSourceModel(model)
            proxy.setHeaderLabels(["Name", "Multiply"])
            self.setModel(proxy)
            self.setRootIndex(proxy.index(0,0))
    ...    
    

    enter image description here