python QstandardItemModel 自然排序
python QstandardItemModel Natural sort
我正在寻找 QstandardItemModel 自然排序方法。我正在阅读一些相关问题并尝试使用我的代码。但是没用
我的工具通过拖放接受一些文件列表。我想按自然排序对我的模型数据进行排序。并将其放入列表视图。
所以这是我的代码:
class VideolistView (QtWidgets.QListView):
def __init__(self, parent):
super(VideolistView, self).__init__(parent)
self.setAcceptDrops(True)
self.setObjectName("VideolistView")
self.setGeometry(QtCore.QRect(8, 30, 250, 301))
self.Model = QtGui.QStandardItemModel(self)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls:
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
if event.mimeData().hasUrls:
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasUrls:
event.setDropAction(QtCore.Qt.CopyAction)
event.accept()
for url in event.mimeData().urls():
dropitem = str(url.toLocalFile())
Fname = os.path.split(dropitem)
if not self.Model.findItems(Fname[1]):
listitem = QtGui.QStandardItem(Fname[1])
self.Model.appendRow(listitem)
self.Model.sort(0)
self.setModel(self.Model)
else:
event.ignore()
我的一些尝试公布。
import re
def _human_key(key):
parts = re.split('(\d*\.\d+|\d+)', key)
return tuple((e.swapcase() if i % 2 == 0 else float(e))
for i, e in enumerate(parts))
......
listitems=[]
for url in event.mimeData().urls():
dropitem = str(url.toLocalFile())
Fname = os.path.split(dropitem)
listitem = QtGui.QStandardItem(Fname[1])
listitems.appent(listitem)
listitems.sort(key=_human_key)
Pycharm 调试错误 listitems.sort(key=_human_key) 我尝试重新实现 QstandardItemModel class
import re
def _human_key(key):
parts = re.split('(\d*\.\d+|\d+)', key)
return tuple((e.swapcase() if i % 2 == 0 else float(e))
for i, e in enumerate(parts))
......
Class NaturalSortModel (QtGui.QstandardItemModel)
def __lt__(self, other):
column = self.treeWidget().sortColumn()
k1 = self.text(column)
k2 = other.text(column)
return _human_key(k1) < _human_key(k2)
.......
Class VideolistView (QtWidgets.QListView)
def __init__(self, parent):
self.Model = self.NaturalSortModel(self)
........
self.Model.appendRow(listitem)
self.Model.sort(0)
self.setModel(self.Model)
........
以上两个代码错误。我如何使用 QstandardItemModel 进行自然排序?
link : Python - Human sort of numbers with alpha numeric, but in pyQt and a __lt__ operator
对于@eyllanesc 的回答,第一个使用 QSortFilterProxyModel 的解决方案效果很好。
它按自然顺序对数据进行排序。
但是@eyllanesc 第二个建议(Qstandarditem inherit)对我不起作用。它像原始来源一样按字母顺序排序。
@eyllanesc 非常感谢!!!
如果你想建立一个特定的顺序标准,你必须通过一个继承自 QSortFilterProxyModel
的模型来实现,并实现方法 lessThan
,如下所示:
class NaturalSortFilterProxyModel(QtCore.QSortFilterProxyModel):
@staticmethod
def _human_key(key):
parts = re.split('(\d*\.\d+|\d+)', key)
return tuple((e.swapcase() if i % 2 == 0 else float(e)) for i, e in enumerate(parts))
def lessThan(self, left, right):
leftData = self.sourceModel().data(left)
rightData = self.sourceModel().data(right)
return self._human_key(leftData) < self._human_key(rightData)
class VideolistView (QtWidgets.QListView):
def __init__(self, parent=None):
super(VideolistView, self).__init__(parent)
self.setAcceptDrops(True)
self.setObjectName("VideolistView")
self.setGeometry(QtCore.QRect(8, 30, 250, 301))
model = QtGui.QStandardItemModel(self)
proxyModel = NaturalSortFilterProxyModel()
proxyModel.setSourceModel(model)
proxyModel.sort(0, QtCore.Qt.AscendingOrder)
self.setModel(proxyModel)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasUrls():
event.setDropAction(QtCore.Qt.CopyAction)
event.accept()
for url in event.mimeData().urls():
dropitem = str(url.toLocalFile())
Fname = os.path.split(dropitem)
if not self.model().sourceModel().findItems(Fname[1]):
listitem = QtGui.QStandardItem(Fname[1])
self.model().sourceModel().appendRow(listitem)
else:
event.ignore()
如@ekhumuro所说,link中显示的解决方案是指创建一个继承自QStandardItem
的class,如下所示
class NaturalStandardItem(QtGui.QStandardItem):
@staticmethod
def _human_key(key):
parts = re.split('(\d*\.\d+|\d+)', key)
return tuple((e.swapcase() if i % 2 == 0 else float(e)) for i, e in enumerate(parts))
def __lt__(self, other):
return self._human_key(self.text()) < self._human_key(other.text())
class VideolistView (QtWidgets.QListView):
def __init__(self, parent=None):
super(VideolistView, self).__init__(parent)
self.setAcceptDrops(True)
self.setObjectName("VideolistView")
self.setGeometry(QtCore.QRect(8, 30, 250, 301))
model = QtGui.QStandardItemModel(self)
self.setModel(model)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasUrls():
event.setDropAction(QtCore.Qt.CopyAction)
event.accept()
for url in event.mimeData().urls():
dropitem = str(url.toLocalFile())
Fname = os.path.split(dropitem)
if not self.model().findItems(Fname[1]):
listitem = NaturalStandardItem(Fname[1])
self.model().appendRow(listitem)
self.model().sort(0)
else:
event.ignore()
我正在寻找 QstandardItemModel 自然排序方法。我正在阅读一些相关问题并尝试使用我的代码。但是没用
我的工具通过拖放接受一些文件列表。我想按自然排序对我的模型数据进行排序。并将其放入列表视图。
所以这是我的代码:
class VideolistView (QtWidgets.QListView):
def __init__(self, parent):
super(VideolistView, self).__init__(parent)
self.setAcceptDrops(True)
self.setObjectName("VideolistView")
self.setGeometry(QtCore.QRect(8, 30, 250, 301))
self.Model = QtGui.QStandardItemModel(self)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls:
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
if event.mimeData().hasUrls:
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasUrls:
event.setDropAction(QtCore.Qt.CopyAction)
event.accept()
for url in event.mimeData().urls():
dropitem = str(url.toLocalFile())
Fname = os.path.split(dropitem)
if not self.Model.findItems(Fname[1]):
listitem = QtGui.QStandardItem(Fname[1])
self.Model.appendRow(listitem)
self.Model.sort(0)
self.setModel(self.Model)
else:
event.ignore()
我的一些尝试公布。
import re
def _human_key(key):
parts = re.split('(\d*\.\d+|\d+)', key)
return tuple((e.swapcase() if i % 2 == 0 else float(e))
for i, e in enumerate(parts))
......
listitems=[]
for url in event.mimeData().urls():
dropitem = str(url.toLocalFile())
Fname = os.path.split(dropitem)
listitem = QtGui.QStandardItem(Fname[1])
listitems.appent(listitem)
listitems.sort(key=_human_key)
Pycharm 调试错误 listitems.sort(key=_human_key) 我尝试重新实现 QstandardItemModel class
import re
def _human_key(key):
parts = re.split('(\d*\.\d+|\d+)', key)
return tuple((e.swapcase() if i % 2 == 0 else float(e))
for i, e in enumerate(parts))
......
Class NaturalSortModel (QtGui.QstandardItemModel)
def __lt__(self, other):
column = self.treeWidget().sortColumn()
k1 = self.text(column)
k2 = other.text(column)
return _human_key(k1) < _human_key(k2)
.......
Class VideolistView (QtWidgets.QListView)
def __init__(self, parent):
self.Model = self.NaturalSortModel(self)
........
self.Model.appendRow(listitem)
self.Model.sort(0)
self.setModel(self.Model)
........
以上两个代码错误。我如何使用 QstandardItemModel 进行自然排序?
link : Python - Human sort of numbers with alpha numeric, but in pyQt and a __lt__ operator
对于@eyllanesc 的回答,第一个使用 QSortFilterProxyModel 的解决方案效果很好。 它按自然顺序对数据进行排序。
但是@eyllanesc 第二个建议(Qstandarditem inherit)对我不起作用。它像原始来源一样按字母顺序排序。 @eyllanesc 非常感谢!!!
如果你想建立一个特定的顺序标准,你必须通过一个继承自 QSortFilterProxyModel
的模型来实现,并实现方法 lessThan
,如下所示:
class NaturalSortFilterProxyModel(QtCore.QSortFilterProxyModel):
@staticmethod
def _human_key(key):
parts = re.split('(\d*\.\d+|\d+)', key)
return tuple((e.swapcase() if i % 2 == 0 else float(e)) for i, e in enumerate(parts))
def lessThan(self, left, right):
leftData = self.sourceModel().data(left)
rightData = self.sourceModel().data(right)
return self._human_key(leftData) < self._human_key(rightData)
class VideolistView (QtWidgets.QListView):
def __init__(self, parent=None):
super(VideolistView, self).__init__(parent)
self.setAcceptDrops(True)
self.setObjectName("VideolistView")
self.setGeometry(QtCore.QRect(8, 30, 250, 301))
model = QtGui.QStandardItemModel(self)
proxyModel = NaturalSortFilterProxyModel()
proxyModel.setSourceModel(model)
proxyModel.sort(0, QtCore.Qt.AscendingOrder)
self.setModel(proxyModel)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasUrls():
event.setDropAction(QtCore.Qt.CopyAction)
event.accept()
for url in event.mimeData().urls():
dropitem = str(url.toLocalFile())
Fname = os.path.split(dropitem)
if not self.model().sourceModel().findItems(Fname[1]):
listitem = QtGui.QStandardItem(Fname[1])
self.model().sourceModel().appendRow(listitem)
else:
event.ignore()
如@ekhumuro所说,link中显示的解决方案是指创建一个继承自QStandardItem
的class,如下所示
class NaturalStandardItem(QtGui.QStandardItem):
@staticmethod
def _human_key(key):
parts = re.split('(\d*\.\d+|\d+)', key)
return tuple((e.swapcase() if i % 2 == 0 else float(e)) for i, e in enumerate(parts))
def __lt__(self, other):
return self._human_key(self.text()) < self._human_key(other.text())
class VideolistView (QtWidgets.QListView):
def __init__(self, parent=None):
super(VideolistView, self).__init__(parent)
self.setAcceptDrops(True)
self.setObjectName("VideolistView")
self.setGeometry(QtCore.QRect(8, 30, 250, 301))
model = QtGui.QStandardItemModel(self)
self.setModel(model)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasUrls():
event.setDropAction(QtCore.Qt.CopyAction)
event.accept()
for url in event.mimeData().urls():
dropitem = str(url.toLocalFile())
Fname = os.path.split(dropitem)
if not self.model().findItems(Fname[1]):
listitem = NaturalStandardItem(Fname[1])
self.model().appendRow(listitem)
self.model().sort(0)
else:
event.ignore()