Рубрики
Без рубрики

WXPYPHON: Как перетащить файл из своего приложения в ОС

Получите практические, реальные навыки Python на наших ресурсах и пути

Автор оригинала: Mike Driscoll.

Сегодня на Stackoverflow Я видел кого-то, кто хотел узнать, как перетащить файл из wx.listctrl на свой рабочий стол или где-то еще в файловой системе. Они использовали скелет менеджера файлов от ZETCode , но не мог понять, как добавить DND-порцию. После небольшого поиска и взлома я придумал это на основании чего-то Робина Данна, упомянутого в Форум Отказ

import wx
import os
import time

########################################################################
class MyListCtrl(wx.ListCtrl):
    
    #----------------------------------------------------------------------
    def __init__(self, parent, id):
        wx.ListCtrl.__init__(self, parent, id, style=wx.LC_REPORT)

        files = os.listdir('.')
        
        self.InsertColumn(0, 'Name')
        self.InsertColumn(1, 'Ext')
        self.InsertColumn(2, 'Size', wx.LIST_FORMAT_RIGHT)
        self.InsertColumn(3, 'Modified')

        self.SetColumnWidth(0, 220)
        self.SetColumnWidth(1, 70)
        self.SetColumnWidth(2, 100)
        self.SetColumnWidth(3, 420)

        j = 0
        for i in files:
            (name, ext) = os.path.splitext(i)
            ex = ext[1:]
            size = os.path.getsize(i)
            sec = os.path.getmtime(i)
            self.InsertStringItem(j, "%s%s" % (name, ext))
            self.SetStringItem(j, 1, ex)
            self.SetStringItem(j, 2, str(size) + ' B')
            self.SetStringItem(j, 3, time.strftime('%Y-%m-%d %H:%M', 
                                                   time.localtime(sec)))

            if os.path.isdir(i):
                self.SetItemImage(j, 1)
            elif ex == 'py':
                self.SetItemImage(j, 2)
            elif ex == 'jpg':
                self.SetItemImage(j, 3)
            elif ex == 'pdf':
                self.SetItemImage(j, 4)
            else:
                self.SetItemImage(j, 0)

            if (j % 2) == 0:
                self.SetItemBackgroundColour(j, '#e6f1f5')
            j = j + 1

########################################################################
class FileHunter(wx.Frame):
    #----------------------------------------------------------------------
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, -1, title)
        panel = wx.Panel(self)

        p1 = MyListCtrl(panel, -1)
        p1.Bind(wx.EVT_LIST_BEGIN_DRAG, self.onDrag)
        sizer = wx.BoxSizer()
        sizer.Add(p1, 1, wx.EXPAND)
        panel.SetSizer(sizer)
        
        self.Center()
        self.Show(True)
        
    #----------------------------------------------------------------------
    def onDrag(self, event):
        """"""
        data = wx.FileDataObject()
        obj = event.GetEventObject()
        id = event.GetIndex()
        filename = obj.GetItem(id).GetText()
        dirname = os.path.dirname(os.path.abspath(os.listdir(".")[0]))
        fullpath = str(os.path.join(dirname, filename))
        
        data.AddFile(fullpath)
        
        dropSource = wx.DropSource(obj)
        dropSource.SetData(data)
        result = dropSource.DoDragDrop()
        print fullpath
        
#----------------------------------------------------------------------
app = wx.App(False)
FileHunter(None, -1, 'File Hunter')
app.MainLoop()

Здесь есть пара важных моментов. Во-первых, вам нужно привязать к evt_list_begin_drag, чтобы поймать соответствующее событие. Затем в вашем обработке вам нужно создать wx.filedataObject объект и использовать его AddFile Способ добавить полный путь к его внутреннему списку файлов. По словам Wxpython Документация AddFile является только для Windows-, однако, поскольку Robin Dunn (Создатель WxPython) рекомендует Этот метод Я пошел с этим. Может быть, документация неверна. Во всяком случае, нам также нужно определить Dropsource и называть его Додрагроп метод, и вы закончите. Этот код работал для меня, как есть на Windows 7, Python 2.6.6 и WXPython 2.8.12.1.