我有一个ListCtrl包含一些代表(巨大和远程)文件的项目。我希望用户能够将项目拖动到打开的目录窗口,从而创建一个文件(真正启动下载)。我希望我的应用程序能够收到“用户将列表项拖到此路径”这样的消息,以便我可以继续将文件数据写入该位置。
我知道如果源文件在本地文件系统上可用,something similar怎么办,但是我的文件很大并且在远程系统上(想想FTP客户端)所以我不能推测性地将它们复制到磁盘中用户想要稍后拖动它们的情况。
如何使用wxpython完成此操作?它甚至可能吗?
答案 0 :(得分:4)
我搜索网络非常努力,但也无法找到办法。甚至Robin Dunn也说当数据被放入文件系统时,drop source app对目标一无所知。但我想出了一个简单的方法,至少在Windows上。我们只需将包含空FileDataObject的DropSource拖到Explorer窗口中。由于没有数据,所有这一切都将Explorer窗口置于顶部,这样我们就可以获得用户拖入的文件夹的路径。首先,请务必将事件绑定到ListCtrl的父级的__init__
def中的ListCtrl:
self.lc.Bind(wx.EVT_LIST_BEGIN_DRAG, self.onDrag)
然后在事件调用的方法中执行此操作:
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's 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
dloadItems方法从ListCtrl获取所选项目,然后(在此应用程序中)将项目从REST服务器下载到outdir。
当然,此解决方案需要pywin32扩展。
祝你好运,麦克
答案 1 :(得分:1)
我不知道如何将其集成到wxpython中,但the shell supports a number of clipboard formats用于复制文件。如果文件在网络驱动器上(例如可通过UNC路径访问),那么您可以使用像CF_DROP格式那样简单的东西。如果它不那么容易,那么您将不得不使用CFSTR_FILEDESCRIPTOR / CFSTR_FILECONTENTS格式。这是用C或C ++实现的一项真正的苦差事,所以我想在python中它会是双倍的。但是,有人可能已经完成了繁重的工作;你应该看看是否有一个python库来处理shell剪贴板格式。
答案 2 :(得分:0)
如果您可以在ListCtrl中显示数据,则可以将列表项绑定到路径。就个人而言,我会使用ObjectListView,因为这使得这类事情变得更加容易。然后,当您执行拖放操作时,可以获取已删除的对象并提取路径/ URL。之后,您只需使用适当的Python库(例如ftplib或urllib)来下载文件。
由于您发现我的博客非常有用,我会指出其他一些可能对您有所帮助的教程: