Drag the file created by the application into the Explorer window

I have a ListCtrl containing some elements representing (huge and deleted) files. I want the user to be able to drag an item into an open directory window and thereby create a file (really initiating the download). I want my application to receive a message like "the user has dragged the list item to this path" in order to continue and write the file data to this place.

I know how to do something similar if the source file is available on the local file system, but my files are large and on the remote (I think the FTP client), so I can not speculatively copy them to disk if the user wants to drag them later.

How can I accomplish this using wxpython? Is it possible?

+4
source share
3 answers

I searched the Internet quite difficult, but could not find a way to do this. Even Robin Dunn says that the source code application does not know anything about the target when the data is deleted to the file system. But I realized that this is an easy way to do this, at least on Windows. We simply drag and drop a DropSource containing an empty FileDataObject into the explorer window. Since there is no data, all this leads to the fact that the Explorer window is at the top, which allows us to get the path to the folder into which the user dragged. First, be sure to bind the event to the ListCtrl element in the __init__ def of the ListCtrl parent:

 self.lc.Bind(wx.EVT_LIST_BEGIN_DRAG, self.onDrag) 

Then do this in the method called by the event:

 def onDrag(self, event): data = wx.FileDataObject() obj = event.GetEventObject() dropSource = wx.DropSource(obj) dropSource.SetData(data) #next line will make the drop target window come to top, allowing us #to get the info we need to do the work, if it Explorer result = dropSource.DoDragDrop(0) #get foreground window hwnd h = win32gui.GetForegroundWindow() #get explorer location s = win32com.client.Dispatch("Shell.Application") loc, outdir = None, None for w in s.Windows(): if int(w.Hwnd) == h: loc = w.LocationURL if loc: outdir = loc.split('///')[1] outdir = urllib.unquote(outdir) #got what we need, now download to outfol if outdir and os.path.isdir(outdir): self.dloadItems(event, outdir) return 

The dloadItems method gets the selected items from ListCtrl, and then (in this application) downloads the items from the REST server to outdir.

This solution requires a pywin32 extension, of course.

good luck

Mike

+3
source

I do not know how to integrate this into wxpython, but the shell supports several clipboard formats for copying files. If the files are located on a network drive (for example, accessible via UNC paths), you can use something as simple as the CF_DROP format. If this is not so simple then you will have to use the format CFSTR_FILEDESCRIPTOR / CFSTR_FILECONTENTS. This is a real task to implement in C or C ++, so I assume it will be doubly in python. Perhaps someone has already made a heavy climb; you should see if there is a python library to handle clipboard formats.

+1
source

If you can display data in ListCtrl, you can bind a list item to a path. Personally, I would use an ObjectListView, as this simplifies this thing. Then, when you drag and drop, you can take the dropped object and extract the path / URL. After that, you just need to use the appropriate Python library, such as ftplib or urllib, to download the file.

Since you found my blog so useful, I’ll list a few other guides that can help you:

0
source

Source: https://habr.com/ru/post/1442839/


All Articles