如何使用QSortFilterProxyModel对文件上方的文件夹进行排序?

时间:2013-11-15 17:13:09

标签: python qt sorting

我有一个QTreeViewQFileSystemModelQSortFilterProxyModel过滤。现在我想将QTreeView中的所有文件夹放在普通文件/链接之上,就像在Nautilus和Dolphin中一样。代理仅按字母顺序排序。我确定我必须创建一个Qt.UserRoleQt.ItemDataRole),但我不知道该怎么做。

import sys
import os

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class Widget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        layout = QVBoxLayout()
        self.setLayout(layout)
        self._view = QTreeView()
        self._view.setRootIsDecorated(False)
        self._view.setAlternatingRowColors(True)
        self._view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self._view.setItemsExpandable(False)
        self._view.setDragEnabled(False)

        self._view.header().setClickable(True)
        self._view.header().setMovable(False)
        self._view.header().setSortIndicatorShown(True)

        layout.addWidget(self._view)

        # Add the model
        self._model = QFileSystemModel()
        self._model.setRootPath(QDir().rootPath())
        self._model.setReadOnly(False)
        self._model.setFilter(QDir.AllDirs | QDir.AllEntries)

        # Add sort proxy
        self._proxy = QSortFilterProxyModel(self)
        self._proxy.setSourceModel(self._model)
        self._view.setModel(self._proxy)

        # sorting
        self._view.header().setSortIndicator(0, Qt.AscendingOrder)
        self._proxy.sort(self._view.header().sortIndicatorSection(),
                         self._view.header().sortIndicatorOrder() )
        QObject.connect(self._view.header(),
                        SIGNAL('sortIndicatorChanged(int,Qt::SortOrder)'),
                        self._proxy.sort )

        # Root path
        path = os.path.dirname(os.path.abspath(__file__))
        self._model.setRootPath(path)

        # Set a root index
        source_index = self._model.index(path)
        index = self._proxy.mapFromSource(source_index)
        self._view.setRootIndex(index)

if __name__ == "__main__":
    app = QApplication(sys.argv)

    widget = Widget()
    widget.show()

    sys.exit(app.exec_())

2 个答案:

答案 0 :(得分:1)

通过继承QSortFilterProxyModel并重新实现lessThan()

来实现自定义排序行为

来自文档...

class MySortFilter(QSortFilterProxyModel):
   def lessThan(self,left,right):   
       leftData = self.sourceModel().data(left)
       rightData = self.sourceModel().data(right)
       leftPath = os.path.abspath(str(leftData.toUrl().toLocalFile() ))
       rightPath = os.path.abspath(str(rightData.toUrl().toLocalFile() ))
       return (not os.path.isdir(leftPath),leftPath)< (not os.path.isdir(rightPath),rightPath )

#now use this class instead of QSortFilterProxyModel

我认为阅读文档会有所作为......我对QT不是很熟悉,所以这就是我从文档中得到的内容

答案 1 :(得分:0)

解决方案更容易!只需使用源模型进行排序而不是代理

        # sorting
        self._view.header().setSortIndicator(0, Qt.AscendingOrder)
        self._model.sort(self._view.header().sortIndicatorSection(),
                         self._view.header().sortIndicatorOrder() )
        QObject.connect(self._view.header(),
                        SIGNAL('sortIndicatorChanged(int,Qt::SortOrder)'),
                        self._model.sort )
BTW问题具有误解性。我只使用QSortFilterProxyModel过滤而不排序。