QSortFilterProxyModel: confusing with lessThan

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

QSortFilterProxyModel: confusing with lessThan

Gottfried Müller
Hello,

in a simple test I want to sort the items in an ascending order using my
own proxy. I expected a comparision of "itemLeft.text() <
itemRight.text()". But I had to code "itemRight.text() <
itemLeft.text()" getting the ascending order.

Gottfried

Here is my example:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# pylint: disable=missing-docstring

import sys

from PyQt5.QtWidgets import QApplication, QTreeView
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtCore import QSortFilterProxyModel


class MyProxy(QSortFilterProxyModel):

     def lessThan(self, mdlIdxSrcLeft, mdlIdxSrcRight):
         mdl = self.sourceModel()
         itemLeft = mdl.itemFromIndex(mdlIdxSrcLeft)
         itemRight = mdl.itemFromIndex(mdlIdxSrcRight)
         return itemRight.text() < itemLeft.text()

     # def filterAcceptsRow(self, srcRow, srcParentIdx):
     #    mdl = self.sourceModel()
     #    itemParent = mdl.itemFromIndex(srcParentIdx)
     #    if itemParent is None:
     #        srcItem = mdl.item(srcRow)
     #    else:
     #        srcItem = itemParent.child(srcRow)
     #    return srcItem.text().isnumeric()


class ApplWindow(QTreeView):

     def __init__(self, parent=None):
         super().__init__(parent)
         self.srcModel = QStandardItemModel(parent=self)
         self.proxy = MyProxy(parent=self)
         self.proxy.setSourceModel(self.srcModel)
         self.setModel(self.proxy)
         self.expandToDepth(0)
         self.setHeaderHidden(True)
         self.setAutoExpandDelay(500)
         self.setSortingEnabled(True)
         self.fillSrcModel()
         self.resize(200, 500)

     def fillSrcModel(self):
         sub = {0: "x2c", 1: "694ad", 2: "t8d2x"}
         for idx01, c01 in enumerate("a2b"):
             item01 = QStandardItem(c01)
             for c02 in sub[idx01]:
                 item02 = QStandardItem(c02)
                 item01.appendRow(item02)
             self.srcModel.appendRow(item01)
         self.expandToDepth(0)

def main():
     appl = QApplication(sys.argv)
     applWindow = ApplWindow()
     applWindow.show()
     return appl.exec_()


if __name__ == "__main__":
     main()

_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: QSortFilterProxyModel: confusing with lessThan

J Barchan


On Tue, 30 Jul 2019 at 09:16, Gottfried Müller <[hidden email]> wrote:
Hello,

in a simple test I want to sort the items in an ascending order using my
own proxy. I expected a comparision of "itemLeft.text() <
itemRight.text()". But I had to code "itemRight.text() <
itemLeft.text()" getting the ascending order.

Gottfried

Here is my example:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# pylint: disable=missing-docstring

import sys

from PyQt5.QtWidgets import QApplication, QTreeView
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtCore import QSortFilterProxyModel


class MyProxy(QSortFilterProxyModel):

     def lessThan(self, mdlIdxSrcLeft, mdlIdxSrcRight):
         mdl = self.sourceModel()
         itemLeft = mdl.itemFromIndex(mdlIdxSrcLeft)
         itemRight = mdl.itemFromIndex(mdlIdxSrcRight)
         return itemRight.text() < itemLeft.text()

     # def filterAcceptsRow(self, srcRow, srcParentIdx):
     #    mdl = self.sourceModel()
     #    itemParent = mdl.itemFromIndex(srcParentIdx)
     #    if itemParent is None:
     #        srcItem = mdl.item(srcRow)
     #    else:
     #        srcItem = itemParent.child(srcRow)
     #    return srcItem.text().isnumeric()


class ApplWindow(QTreeView):

     def __init__(self, parent=None):
         super().__init__(parent)
         self.srcModel = QStandardItemModel(parent=self)
         self.proxy = MyProxy(parent=self)
         self.proxy.setSourceModel(self.srcModel)
         self.setModel(self.proxy)
         self.expandToDepth(0)
         self.setHeaderHidden(True)
         self.setAutoExpandDelay(500)
         self.setSortingEnabled(True)
         self.fillSrcModel()
         self.resize(200, 500)

     def fillSrcModel(self):
         sub = {0: "x2c", 1: "694ad", 2: "t8d2x"}
         for idx01, c01 in enumerate("a2b"):
             item01 = QStandardItem(c01)
             for c02 in sub[idx01]:
                 item02 = QStandardItem(c02)
                 item01.appendRow(item02)
             self.srcModel.appendRow(item01)
         self.expandToDepth(0)

def main():
     appl = QApplication(sys.argv)
     applWindow = ApplWindow()
     applWindow.show()
     return appl.exec_()


if __name__ == "__main__":
     main()

_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt

It should indeed be itemLeft.text() < itemRight.text() (for ascending order) in lessThan(self, mdlIdxSrcLeft, mdlIdxSrcRight).  Yours will do descending order.  I suggest you look again at your code/try a standalone test.


--
Kindest,
Jonathan

_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
Reply | Threaded
Open this post in threaded view
|

Re: QSortFilterProxyModel: confusing with lessThan

Maurizio Berti
In reply to this post by Gottfried Müller
Il giorno mar 30 lug 2019 alle ore 10:17 Gottfried Müller <[hidden email]> ha scritto:
in a simple test I want to sort the items in an ascending order using my
own proxy. I expected a comparision of "itemLeft.text() <
itemRight.text()". But I had to code "itemRight.text() <
itemLeft.text()" getting the ascending order.

If you print self.proxy.sortOrder() you'll find out that you're currently using a descending order, which is why you've to invert the comparison.
I suppose that's due to the default sortIndicatorOrder of the QTreeView header, which seems to be set to DescendingOrder if the indicator is not shown.
Just use self.sortByColumn(0, QtCore.Qt.AscendingOrder) and it will work.

Maurizio


--
È difficile avere una convinzione precisa quando si parla delle ragioni del cuore. - "Sostiene Pereira", Antonio Tabucchi
http://www.jidesk.net

_______________________________________________
PyQt mailing list    [hidden email]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt