PyQt QListView 拖放导入和重排问题

4 投票
1 回答
3566 浏览
提问于 2025-04-17 18:38

我现在的列表视图代码可以让我把电脑里的文件拖放到列表视图里。可是我想要的功能是能重新排列列表里的项目。问题是,当我尝试这样做时,它会被导入文件的拖放方法覆盖,什么也不发生。举个例子,如果我从列表视图外面拖东西进来,我希望它能导入;但如果是从列表视图内部拖动,我希望它能像内部移动那样简单地移动。

我在代码里加了这个:

self.listView.setDragDropMode(QtGui.QAbstractItemView.InternalMove);

同时注释掉这个:

def dropEvent(self, event):
    if event.mimeData().hasUrls:
        event.setDropAction(QtCore.Qt.CopyAction)
        event.accept()
        links = []
        for url in event.mimeData().urls():
            links.append(str(url.toLocalFile()))
        self.emit(QtCore.SIGNAL("dropped"), links)
    else:
        event.ignore()

这样一来,重新排列就能顺利工作,但我就不能通过拖动来导入文件了。

因此,我认为上面的代码是我遇到问题的原因,但我就是搞不清楚怎么才能同时让这两个功能都能用,感觉应该是个简单的解决办法。

我不知道这是不是正确的方向,但我知道:

if event.mimeData().hasUrls:

如果是从列表视图外面拖来,返回true;如果是在列表视图内部,返回false。

你可能会注意到,上面的代码来自: http://tech.xster.net/tips/pyqt-drag-images-into-list-widget-for-thumbnail-list/http://zetcode.com/tutorials/pyqt4/dragdrop/

我知道我可以创建一个设置,查询鼠标位置,然后删除项目并在最近的位置重新添加,但这看起来太麻烦了,因为内部移动功能已经内置并且满足我的需求。

任何帮助都将非常感谢,感谢你的时间!

1 个回答

4

Piotr的回答离我想要的答案还有一段距离。其实我在这里找到了我问题的其余部分 -> http://sjt.is/2012/05/23/pyqt-and-dragndrop/

我简单地把我的列表视图定义为:

mylist = TestListView(self)

然后用下面的代码作为类的定义:

class TestListView(QtGui.QListWidget):

    def __init__(self, parent):
        super(TestListView, self).__init__(parent)
        self.setAcceptDrops(True)
        self.setIconSize(QtCore.QSize(100, 100))
        self.itemClicked.connect(self.on_item_clicked)
        self.setDragDropMode(QtGui.QAbstractItemView.InternalMove)


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

    def dragMoveEvent(self, event):
        super(TestListView, self).dragMoveEvent(event)

    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))
            self.emit(QtCore.SIGNAL("dropped"), links)
            event.acceptProposedAction()
        else:
            super(TestListView,self).dropEvent(event)

当新的文件被拖放进来时,它会发出一个信号,连接到列表视图的一个函数。当旧的文件被拖放时,它会被移动。谢谢大家的帮助!

撰写回答