wxPython - Drag & Drop

Fornitura di drag and dropè molto intuitivo per l'utente. Si trova in molte applicazioni desktop in cui l'utente può copiare o spostare oggetti da una finestra all'altra semplicemente trascinandoli con il mouse e rilasciandoli su un'altra finestra.

L'operazione di trascinamento della selezione prevede i seguenti passaggi:

  • Dichiara un obiettivo di rilascio
  • Crea oggetto dati
  • Crea wx.DropSource
  • Eseguire l'operazione di trascinamento
  • Annulla o accetta il rilascio

In wxPython, ci sono due destinazioni di rilascio predefinite:

  • wx.TextDropTarget
  • wx.FileDropTarget

Molti widget wxPython supportano l'attività di trascinamento della selezione. Il controllo del codice sorgente deve avere il trascinamento abilitato, mentre il controllo di destinazione deve essere in grado di accettare (o rifiutare) il trascinamento.

I dati di origine che l'utente sta trascinando vengono posizionati sull'oggetto di destinazione. OnDropText () dell'oggetto di destinazione consuma i dati. Se lo si desidera, è possibile eliminare i dati dall'oggetto di origine.

Esempio

Nell'esempio seguente, due oggetti ListCrl vengono posizionati orizzontalmente in un Box Sizer. L'elenco a sinistra è popolato con i dati delle lingue []. È designato come fonte di trascinamento. Quello a destra è il bersaglio.

languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript', 'PHP', 'VB.NET','C#'] 
self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 
self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 

   for lang in languages: 
      self.lst1.InsertStringItem(0,lang)

Il secondo controllo elenco è vuoto ed è un argomento per l'oggetto della classe TextDropTarget.

class MyTextDropTarget(wx.TextDropTarget):
   def __init__(self, object): 
      wx.TextDropTarget.__init__(self) 
      self.object = object
		
   def OnDropText(self, x, y, data): 
      self.object.InsertStringItem(0, data)

Il metodo OnDropText () aggiunge i dati di origine nel controllo dell'elenco di destinazione.

L'operazione di trascinamento viene inizializzata dal raccoglitore di eventi.

wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)

La funzione OnDragInit () inserisce i dati di trascinamento sulla destinazione ed elimina dall'origine.

def OnDragInit(self, event): 
   text = self.lst1.GetItemText(event.GetIndex()) 
   tobj = wx.PyTextDataObject(text) 
   src = wx.DropSource(self.lst1) 
   src.SetData(tobj) 
   src.DoDragDrop(True) 
   self.lst1.DeleteItem(event.GetIndex())

Il codice completo è il seguente:

import wx
  
class MyTarget(wx.TextDropTarget): 
   def __init__(self, object): 
      wx.TextDropTarget.__init__(self) 
      self.object = object  
		
   def OnDropText(self, x, y, data): 
      self.object.InsertStringItem(0, data)  
		
class Mywin(wx.Frame): 
            
   def __init__(self, parent, title): 
      super(Mywin, self).__init__(parent, title = title,size = (-1,300))   
      panel = wx.Panel(self) 
      box = wx.BoxSizer(wx.HORIZONTAL)  
      languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript',
         'PHP', 'VB.NET','C#']
			
      self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 
      self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) 
      for lang in languages: 
      self.lst1.InsertStringItem(0,lang) 
             
      dt = MyTarget(self.lst2) 
      self.lst2.SetDropTarget(dt) 
      wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)
		
      box.Add(self.lst1,0,wx.EXPAND) 
      box.Add(self.lst2, 1, wx.EXPAND) 
		
      panel.SetSizer(box) 
      panel.Fit() 
      self.Centre() 
      self.Show(True)  
     
   def OnDragInit(self, event): 
      text = self.lst1.GetItemText(event.GetIndex()) 
      tobj = wx.PyTextDataObject(text) 
      src = wx.DropSource(self.lst1) 
      src.SetData(tobj) 
      src.DoDragDrop(True) 
      self.lst1.DeleteItem(event.GetIndex()) 
		
ex = wx.App() 
Mywin(None,'Drag&Drop Demo') 
ex.MainLoop()

Il codice precedente produce il seguente output: