Wxpython 简明教程

wxPython - Drag & Drop

提供 drag and drop 对于用户而言非常直观。它会在很多桌面应用程序中找到,用户只需使用鼠标拖放就能从一个窗口复制或移动对象到另一个窗口。

拖放操作涉及以下步骤:

  1. Declare a drop target

  2. Create data object

  3. Create wx.DropSource

  4. Execute drag operation

  5. Cancel or accept drop

在 wxPython 中,有两个预定义的下放目标:

  1. wx.TextDropTarget

  2. wx.FileDropTarget

许多 wxPython 小组件支持拖放活动。源控件必须启用拖放,而目标控件必须处于可接受(或拒绝)拖拽的位置。

用户正在拖拽的源数据被置于目标对象上。目标对象的 OnDropText() 消耗该数据。如果需要,源对象中的数据可以被删除。

Example

在下面的示例中,两个 ListCrl 对象被水平放置在一个框 Sizer 中。左侧的列表填充有 languages[] 数据。它被指定为拖拽的源。右侧的列表是目标。

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)

第二个列表控件为空,并且是 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)

OnDropText() 方法将源数据添加到目标列表控件中。

拖拽操作是由事件绑定器初始化的。

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

OnDragInit() 函数将拖拽数据放到目标上并从源中将其删除。

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())

完整代码如下所示:

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()

上述代码生成以下输出 -

drag drop output