0

I want to create a PyQt application where the user can drag and drop files onto a listview (or similar widget) and those files will be added to the list. This much works in the following example.

If the user drags an item from the listview to their desktop (outside/external from app) for example, I also want my python program to detect/print the path where the item was dropped (e.g. C:\Users\alilly\Desktop). Then I can write the code to copy files to that location.

This is the partially working code I have so far.

import sys from PyQt4.QtGui import * from PyQt4.QtCore import *

class MyListWidget(QListWidget):
  def __init__(self, parent):
    super(MyListWidget, self).__init__(parent)
    self.setAcceptDrops(True)
    self.setDragEnabled(True)
    self.setDragDropMode(QAbstractItemView.InternalMove)

  def mouseMoveEvent(self, event):
    self.dragObject()

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

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

  def dropEvent(self, event):
    if event.mimeData().hasUrls():
      for url in event.mimeData().urls():
        self.addItem(url.path())
      event.acceptProposedAction()
    else:
      super(MyListWidget,self).dropEvent(event)

  def dragObject(self):
    if not self.selectedIndexes(): return

    drag = QDrag(self)

    data = []
    for index in self.selectedIndexes():
        if not index.isValid(): continue

        # this assumes your model has a nodeFromIndex() method -
        # it's easy to set one up, you'll probably have a custom
        # model class anyways
        # node = self.model().nodeFromIndex(index)
        # data.append(str(node))

    # in this case I'm just making a newline-seperated list
    # of the data, you could do pretty much anything here
    md = QMimeData()
    md.setData('text/plain', "\n".join(data))

    # this is important.  Without this, it won't do anything.
    # you can use different actions like Qt.MoveAction, which
    # would remove the item from your model, but then your model
    # has to be more complicated.  I'm only interested in copy here.
    drag.setMimeData(md)
    dropAction = drag.exec_(Qt.CopyAction)

class MyWindow(QWidget):
  def __init__(self):
    super(MyWindow,self).__init__()
    self.setGeometry(100,100,300,400)
    self.setWindowTitle("Filenames")

    self.list = MyListWidget(self)
    layout = QVBoxLayout(self)
    layout.addWidget(self.list)

    self.setLayout(layout)

if __name__ == '__main__':

  app = QApplication(sys.argv)
  app.setStyle("plastique")

  window = MyWindow()
  window.show()

  sys.exit(app.exec_())
4

1 回答 1

2

Not sure about other platforms but on Windows you don't need to write your own code to copy or move the files. Just add the files path to the mimedata using 'text/uri-list' and windows will copy/move it to the drop location

testFile = 'file:///C:/testFile.txt'
md = QMimeData()
md.setData('text/uri-list', QtCore.QByteArray(testFile))
于 2013-07-24T14:53:05.940 回答