首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python QstandardItemModel自然排序

python QstandardItemModel自然排序
EN

Stack Overflow用户
提问于 2017-10-05 10:00:45
回答 1查看 1.2K关注 0票数 1

我在寻找QstandardItemModel自然排序方法。我正在阅读一些相关的问题,并尝试我的代码。但这不起作用

我的工具通过拖放接受一些文件列表。我想按自然排序对我的模型数据进行排序。把它放到列表中。

这是我的密码:

代码语言:javascript
复制
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()

我的主播宣布。

代码语言:javascript
复制
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类

代码语言:javascript
复制
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做自然排序的?

链接: operator

有了@eyllanesc的答案,QSortFilterProxyModel的第一个解决方案就能很好地工作。它按自然顺序对数据进行排序。

但是@eyllanesc第二个建议(Qstandarditem inherit)并不适合我。它按字母顺序排序,就像原始源一样。@eyllanesc非常感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-05 13:54:52

如果您想要建立一个特定的有序性标准,就必须通过一个继承自QSortFilterProxyModel的模型并实现lessThan方法,如下所示:

代码语言:javascript
复制
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所说,链接中显示的解决方案是创建一个继承自QStandardItem的类,如下所示

代码语言:javascript
复制
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()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46582893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档