Search code examples
pyqtqtreeviewqsortfilterproxymodel

How to get correct data from QSortFilterProxyModel PyQt


I have a QTreeView with QSortFilterProxyModel. When I click on any item of the view, this prints the index from the clicked row. Before and after setting the filter it prints the same index.

I need this for removeRow(), but when I put index, it removes the incorrect item from the list :/

How to delete the correct selected row?

Example:

Not Sorted

 ITEM 1
 ITEM 2 -> Click: Print ITEM2 and this is removed
 ITEM 3
 ITEM 4

Sorted

ITEM 2
ITEM 4 -> Click: Print ITEM2 and ITEM2 is removed :/

init
    self.menuIndex = None

    self.mModelMenu = QtGui.QStandardItemModel(0, 4, self)
    self.mModelMenu.setHeaderData(0, QtCore.Qt.Horizontal, "Id")
    self.mModelMenu.setHeaderData(1, QtCore.Qt.Horizontal, "Descripcion")
    self.mModelMenu.setHeaderData(2, QtCore.Qt.Horizontal, "Categoria")
    self.mModelMenu.setHeaderData(3, QtCore.Qt.Horizontal, "Cantidad")

    self.mProxyModelMenu = QtGui.QSortFilterProxyModel()
    self.mProxyModelMenu.setDynamicSortFilter(True)
    self.mProxyModelMenu.setSourceModel(self.mModelMenu)

    self.mTreeView = QtGui.QTreeView()
    self.mTreeView.setRootIsDecorated(False)
    self.mTreeView.setAlternatingRowColors(True)
    self.mTreeView.setModel(self.mProxyModelMenu)
    self.mTreeView.setSortingEnabled(True)
    self.mTreeView.sortByColumn(0, QtCore.Qt.AscendingOrder)
    self.mTreeView.resizeColumnToContents(0)
    self.mTreeView.clicked.connect(self.getIndex)

    mPushButton1 = QtGui.QPushButton("Borrar")
    mPushButton1.clicked.connect(self.newInMenu)

def getIndex()
    print(index.row())
    self.menuIndex = index.data(index.row())
    print(index.data(index.row()))
    # print(index.data(QtCore.Qt.DisplayRole))

def removeFromMenu(self):
    toRemove = self.menuIndex
    self.mModelMenu.removeRow(0) #this delete the last row, but i need delete current selected row

Solution

  • The simplest way to work with the proxy model is to avoid working on the original model and use QSortFilterProxyModel methods when possible.

    E.g. simply invoking removeRow on the proxy model:

    def removeFromMenu(self)
        selIndexes = self.mTreeView.selectedIndexes()
        if len(selIndexes):
            first = selIndexes[0]
            self.mProxyModelMenu.removeRow(first.row(), first.parent())
    

    should do the trick.