QStandardItemModel с несколькими заголовками — отделить заголовок QTreeView от модели

У меня есть QStandardItemModel, которому нужны разные горизонтальные метки заголовков в разных представлениях.

У меня возникли проблемы с поиском информации о том, как таким образом отделить заголовок QTreeView от модели. Это возможно?

См. простой пример кода ниже.


В этом примере у нас есть ItemTypeA, который является нашим элементом верхнего уровня, и его горизонтальная ось представляет атрибуты Name | интерполяция | нормализовать.

Дочерние элементы ItemTypeA (ItemTypeB) имеют элементы на горизонтальной оси, которые представляют Name | Умножить

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

Мысли?


person stowaway    schedule 19.04.2018    source источник


Ответы (1)


Решением для этих случаев будет использование QIdentityProxyModel, но этот класс отсутствует в PySide и PySide, поэтому мы должны использовать аналогичный класс, такой как QSortFilterProxyModel, и перезаписать метод 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))
...    

введите здесь описание изображения

person eyllanesc    schedule 19.04.2018