1

我有一个QListWidget允许拖放文件。这是一个非常标准的表格,已经被广泛覆盖。我在下面复制的代码有效。

我遇到的问题是列表小部件中文件条目的顺序。为了说明我的问题,假设用户(通过按住 shift、ctrl 或其他方式)选择了四个按 Windows 文件资源管理器中所述命名1.txt, 2.txt, 3.txt和排序的文件。4.txt当用户拖动这四个选定的文件时,我希望它们以相同的顺序附加到列表小部件中。

但是,实际上发生的情况是,列表中的第一个文件取决于在拖放操作开始时碰巧单击了所选组中的哪个文件。假设用户在开始拖动时单击3.txt:然后列表小部件将填充为3.txt, 4.txt, 1.txt, 2.txt. 我想通过忽略在拖动操作开始时作为所选组的一部分碰巧单击的任何文件来保留文件在 Windows 文件管理器中的顺序。我进行了广泛的搜索,但没有找到解决方案。

class FileList(QtGui.QListWidget):
    enableRun = QtCore.pyqtSignal(bool)
    defaultFilePath = QtCore.pyqtSignal(str)

    def __init__(self):
        super(FileList,self).__init__()

        self.setAcceptDrops(True)
        self.setDragEnabled(True)
        self.setDropIndicatorShown(True)
        self.setToolTip('Drag and drop files that you wish to combine')
        self.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
        self.setAlternatingRowColors(True)
        self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)

        self.itemDoubleClicked.connect(self.remove)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
          event.acceptProposedAction()
        else:
          super(FileList, self).dragEnterEvent(event)

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
            event.acceptProposedAction()
        else:
            super(FileList, self).dragMoveEvent(event)

    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(QtCore.Qt.MoveAction)
            self.defaultFilePath.emit(str(event.mimeData().urls()[0].toLocalFile()))
            for url in event.mimeData().urls():
                self.addItem(str(url.toLocalFile()))
        else:
            super(FileList, self).dropEvent(event)

        self.checkCount()

    def dragLeaveEvent(self,event):
        for item in self.selectedItems():
            self.takeItem(self.row(item))
        self.checkCount()

    def remove(self,item):
        self.takeItem(self.row(item))
        self.checkCount()

    def checkCount(self):
        if self.count() >= 2:
            self.enableRun.emit(True)
        else:
            self.enableRun.emit(False)

    def clear(self):
        super(FileList,self).clear()
        self.checkCount()
4

2 回答 2

0

看起来当前的行为是最佳的。

在拖放过程中会保留选择的顺序,因为没有其他方法可以恢复该信息。潜在地,这可以让用户完全控制拖动的项目在列表中的显示方式。如果他们希望它们以某种特定顺序(包括当前在文件管理器中显示的顺序),他们可以根据需要简单地选择它们。

相比之下,文件管理器使用的排序顺序很容易复制,因此尝试保留它没有什么价值。甚至不清楚这样做是否有意义。如果文件管理器在拖放操作期间或之后立即更新怎么办?“正确”的顺序应该是什么?

理想情况下,应用程序应该在将 url 加载到列表中时尝试保留用户的选择顺序,然后提供一种对其进行排序/取消排序的方法。第二好的可能是按字母顺序对其进行排序,因为这是大多数用户无论如何都希望发生的。

于 2015-04-14T18:45:35.410 回答
0

尝试在 dropEvent 中指定 QListWidget 的排序顺序。此示例将按字母升序对文件进行排序,例如:1.txt、2.txt、3.txt ...

    self.sortItems(QtCore.Qt.AscendingOrder)
于 2015-04-14T10:33:04.743 回答