拖放文件网址顺序

时间:2013-04-04 19:04:02

标签: python-3.x drag-and-drop pyqt qlistwidget

我有一个允许拖放文件的QListWidget。这是一个非常标准的形式,已被广泛涵盖。我在下面复制的代码可以使用。

我遇到的问题是文件条目进入列表小部件的顺序。为了说明我的问题,请说用户(通过按住Shift,ctrl或其他方式)选择四个文件,如Windows文件浏览器中所述,命名为1.txt, 2.txt, 3.txt4.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()

2 个答案:

答案 0 :(得分:0)

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

    self.sortItems(QtCore.Qt.AscendingOrder)

答案 1 :(得分:0)

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

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

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

理想情况下,应用程序应该在将URL加载到列表时尝试保留用户的选择顺序,然后提供一种方法来对其进行排序/取消。第二好的可能就是按字母顺序排序,因为这是大多数用户预期会发生的事情。