[英]How to sort folders above files with QSortFilterProxyModel?
I have a QTreeView
with a QFileSystemModel
which is filtered by QSortFilterProxyModel
. 我有一个
QTreeView
的QFileSystemModel
,它由QSortFilterProxyModel
过滤。 Now I would like to have all folders in QTreeView
above the normal files/links like it is by default in Nautilus and Dolphin. 现在,我想让
QTreeView
所有文件夹都位于正常文件/链接上方,就像Nautilus和Dolphin中的默认设置一样。 The proxy only sort by alphabetic order by now. 现在,代理仅按字母顺序排序。 I'm sure I'd have to create a
Qt.UserRole
( Qt.ItemDataRole ) but I've no clue how to do that. 我确定我必须创建一个
Qt.UserRole
( Qt.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_())
Custom sorting behavior is achieved by subclassing QSortFilterProxyModel and reimplementing lessThan()
通过子类化QSortFilterProxyModel并重新实现
lessThan()
,可以实现自定义排序行为
from the docs ... 从文档中...
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
I think would work from reading the docs ... Im not very familliar with QT though so this is just what I got from the docs 我认为可以通过阅读文档来工作...尽管我对QT不太熟悉,所以这正是我从文档中获得的
Solution is lot easier! 解决方案容易得多! Just use source model for sort instead of proxy
只需使用源模型进行排序,而不是使用代理
# 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 Question was missleading. 顺便说一句,问题是误导。 I used
QSortFilterProxyModel
only to filter not sort. 我仅使用
QSortFilterProxyModel
进行过滤而不进行排序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.