1

I have a QStandardItemModel that needs different horizontal header labels in different views.

I'm having trouble finding information about how to decouple the header of a QTreeView from the model in that way. Is this possible?

See a simple code example below.


In this example - we have ItemTypeA, which is our top level item, and its horizontal axis represents the attributes "Name | Interpolaton | Normalize".

The children of ItemTypeA (ItemTypeB) have items in the horizontal axis that represent "Name | Multiply"

TreeViewA shows everything, and TreeViewB only shows the children of the selected Top Level Item (selection connection not implemented in this example).

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()

Thoughts?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
stowaway
  • 77
  • 9

1 Answers1

2

The solution for these cases would be to use QIdentityProxyModel but this class is not present in PySide and PySide, so we must use a similar class such as QSortFilterProxyModel and overwrite the headerData method.

...

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

eyllanesc
  • 235,170
  • 19
  • 170
  • 241