wxpython 拖放:仅当光标在目标 listctrl 对象内时才放下
wxpython drag and drop: drop only if the cursor is inside the target listctrl object
我正在尝试使用 wxpython
创建一个小型应用程序,用户可以在其中从 listctrl
对象(源)拖动一些文本并将其放入另一个 listctrl
对象(目标)。
我想以这样的方式编写此应用程序,即仅当光标位于目标 listctrl
区域时 将文本字符串放入目标 listctrl
对象. 我的代码(如下所示)现在将放置一个文本字符串,即使光标永远不会移动到目标区域。任何指针将不胜感激!
import wx
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
class TextDropTargetListCtrl(wx.TextDropTarget):
def __init__(self, object):
wx.TextDropTarget.__init__(self)
self.object = object
def OnDropText(self, x, y, data):
self.object.InsertStringItem(0, data)
def OnDragOver(self, x, y, d):
return wx.DragCopy
class AutoWidthListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
def __init__(self, parent, style):
wx.ListCtrl.__init__(self, parent, -1, style=style)
ListCtrlAutoWidthMixin.__init__(self)
class MainApp(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="", size=(500, 800))
self.SetBackgroundColour('white')
self.GridBagSizer = wx.GridBagSizer()
self.listctrl_left = AutoWidthListCtrl(self, style = wx.LC_REPORT|wx.LC_VRULES)
self.listctrl_left.InsertColumn(0, "Source")
self.listctrl_left.InsertStringItem(0, "apple")
self.listctrl_left.InsertStringItem(1, "pear")
self.listctrl_left.InsertStringItem(2, "watermelon")
self.listctrl_right = AutoWidthListCtrl(self, style = wx.LC_REPORT)
self.listctrl_right.InsertColumn(0, "Destination")
self.GridBagSizer.Add(self.listctrl_left, pos=(0, 0),span = (1, 1),
flag = wx.EXPAND|wx.ALL, border = 15)
self.GridBagSizer.Add(self.listctrl_right, pos=(0, 1),span = (1, 1),
flag = wx.EXPAND|wx.ALL, border = 15)
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.OnDragInit)
self.DropTarget = TextDropTargetListCtrl(self.listctrl_right)
self.GridBagSizer.AddGrowableCol(0)
self.GridBagSizer.AddGrowableCol(1)
self.GridBagSizer.AddGrowableRow(0)
self.SetSizer(self.GridBagSizer)
def OnDragInit(self, evt):
text = self.listctrl_left.GetItemText(evt.GetIndex())
tdo = wx.TextDataObject(text)
tds = wx.DropSource(self.listctrl_left)
tds.SetData(tdo)
tds.DoDragDrop(True)
if __name__ == "__main__":
app = wx.App()
MainFrame = MainApp()
MainFrame.Show()
MainFrame.Centre()
app.MainLoop()
import wx
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
class TextDropTargetListCtrl(wx.TextDropTarget):
def __init__(self, object, parent):
wx.TextDropTarget.__init__(self)
self.object = object
self.parent = parent
def OnDropText(self, x, y, data):
_x,_y = self.parent.listctrl_right.GetPosition()
_w,_h = self.parent.listctrl_right.GetSize()
# print _x, _w
# if self.parent.hovering:
if _x < x < _x+_w:
self.object.InsertStringItem(0, data)
def OnDragOver(self, x, y, d):
return wx.DragCopy
class AutoWidthListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
def __init__(self, parent, style):
wx.ListCtrl.__init__(self, parent, -1, style=style)
ListCtrlAutoWidthMixin.__init__(self)
class MainApp(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="", size=(500, 800))
self.SetBackgroundColour('white')
self.GridBagSizer = wx.GridBagSizer()
self.listctrl_left = AutoWidthListCtrl(self, style = wx.LC_REPORT|wx.LC_VRULES)
self.listctrl_left.InsertColumn(0, "Source")
self.listctrl_left.InsertStringItem(0, "apple")
self.listctrl_left.InsertStringItem(1, "pear")
self.listctrl_left.InsertStringItem(2, "watermelon")
self.listctrl_right = AutoWidthListCtrl(self, style = wx.LC_REPORT)
self.listctrl_right.InsertColumn(0, "Destination")
# self.listctrl_right.Bind(wx.EVT_ENTER_WINDOW, self.OnHoverEnter)
# self.listctrl_right.Bind(wx.EVT_LEAVE_WINDOW, self.OnHoverLeave)
# self.hovering = False
self.GridBagSizer.Add(self.listctrl_left, pos=(0, 0),span = (1, 1),
flag = wx.EXPAND|wx.ALL, border = 15)
self.GridBagSizer.Add(self.listctrl_right, pos=(0, 1),span = (1, 1),
flag = wx.EXPAND|wx.ALL, border = 15)
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.OnDragInit)
self.DropTarget = TextDropTargetListCtrl(self.listctrl_right, self)
self.GridBagSizer.AddGrowableCol(0)
self.GridBagSizer.AddGrowableCol(1)
self.GridBagSizer.AddGrowableRow(0)
self.SetSizer(self.GridBagSizer)
# def OnHoverEnter(self, event):
# self.hovering = True
# def OnHoverLeave(self, event):
# self.hovering = False
def OnDragInit(self, evt):
text = self.listctrl_left.GetItemText(evt.GetIndex())
tdo = wx.TextDataObject(text)
tds = wx.DropSource(self.listctrl_left)
tds.SetData(tdo)
tds.DoDragDrop(True)
# evt.Skip()
if __name__ == "__main__":
app = wx.App()
MainFrame = MainApp()
MainFrame.Show()
MainFrame.Centre()
app.MainLoop()
这非常骇人听闻,但可以做你想做的事...最初我尝试了 EVT_ENTER_WINDOW
和 EVT_LEAVE_WINDOW
事件,它们在 listctrl 上运行正常,但 在拖动时没有运行 [=16] =].所以,我只是检查了 drop 事件的 x 坐标是否落在正确的 listctrl 小部件内。
我正在尝试使用 wxpython
创建一个小型应用程序,用户可以在其中从 listctrl
对象(源)拖动一些文本并将其放入另一个 listctrl
对象(目标)。
我想以这样的方式编写此应用程序,即仅当光标位于目标 listctrl
区域时 将文本字符串放入目标 listctrl
对象. 我的代码(如下所示)现在将放置一个文本字符串,即使光标永远不会移动到目标区域。任何指针将不胜感激!
import wx
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
class TextDropTargetListCtrl(wx.TextDropTarget):
def __init__(self, object):
wx.TextDropTarget.__init__(self)
self.object = object
def OnDropText(self, x, y, data):
self.object.InsertStringItem(0, data)
def OnDragOver(self, x, y, d):
return wx.DragCopy
class AutoWidthListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
def __init__(self, parent, style):
wx.ListCtrl.__init__(self, parent, -1, style=style)
ListCtrlAutoWidthMixin.__init__(self)
class MainApp(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="", size=(500, 800))
self.SetBackgroundColour('white')
self.GridBagSizer = wx.GridBagSizer()
self.listctrl_left = AutoWidthListCtrl(self, style = wx.LC_REPORT|wx.LC_VRULES)
self.listctrl_left.InsertColumn(0, "Source")
self.listctrl_left.InsertStringItem(0, "apple")
self.listctrl_left.InsertStringItem(1, "pear")
self.listctrl_left.InsertStringItem(2, "watermelon")
self.listctrl_right = AutoWidthListCtrl(self, style = wx.LC_REPORT)
self.listctrl_right.InsertColumn(0, "Destination")
self.GridBagSizer.Add(self.listctrl_left, pos=(0, 0),span = (1, 1),
flag = wx.EXPAND|wx.ALL, border = 15)
self.GridBagSizer.Add(self.listctrl_right, pos=(0, 1),span = (1, 1),
flag = wx.EXPAND|wx.ALL, border = 15)
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.OnDragInit)
self.DropTarget = TextDropTargetListCtrl(self.listctrl_right)
self.GridBagSizer.AddGrowableCol(0)
self.GridBagSizer.AddGrowableCol(1)
self.GridBagSizer.AddGrowableRow(0)
self.SetSizer(self.GridBagSizer)
def OnDragInit(self, evt):
text = self.listctrl_left.GetItemText(evt.GetIndex())
tdo = wx.TextDataObject(text)
tds = wx.DropSource(self.listctrl_left)
tds.SetData(tdo)
tds.DoDragDrop(True)
if __name__ == "__main__":
app = wx.App()
MainFrame = MainApp()
MainFrame.Show()
MainFrame.Centre()
app.MainLoop()
import wx
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
class TextDropTargetListCtrl(wx.TextDropTarget):
def __init__(self, object, parent):
wx.TextDropTarget.__init__(self)
self.object = object
self.parent = parent
def OnDropText(self, x, y, data):
_x,_y = self.parent.listctrl_right.GetPosition()
_w,_h = self.parent.listctrl_right.GetSize()
# print _x, _w
# if self.parent.hovering:
if _x < x < _x+_w:
self.object.InsertStringItem(0, data)
def OnDragOver(self, x, y, d):
return wx.DragCopy
class AutoWidthListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
def __init__(self, parent, style):
wx.ListCtrl.__init__(self, parent, -1, style=style)
ListCtrlAutoWidthMixin.__init__(self)
class MainApp(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="", size=(500, 800))
self.SetBackgroundColour('white')
self.GridBagSizer = wx.GridBagSizer()
self.listctrl_left = AutoWidthListCtrl(self, style = wx.LC_REPORT|wx.LC_VRULES)
self.listctrl_left.InsertColumn(0, "Source")
self.listctrl_left.InsertStringItem(0, "apple")
self.listctrl_left.InsertStringItem(1, "pear")
self.listctrl_left.InsertStringItem(2, "watermelon")
self.listctrl_right = AutoWidthListCtrl(self, style = wx.LC_REPORT)
self.listctrl_right.InsertColumn(0, "Destination")
# self.listctrl_right.Bind(wx.EVT_ENTER_WINDOW, self.OnHoverEnter)
# self.listctrl_right.Bind(wx.EVT_LEAVE_WINDOW, self.OnHoverLeave)
# self.hovering = False
self.GridBagSizer.Add(self.listctrl_left, pos=(0, 0),span = (1, 1),
flag = wx.EXPAND|wx.ALL, border = 15)
self.GridBagSizer.Add(self.listctrl_right, pos=(0, 1),span = (1, 1),
flag = wx.EXPAND|wx.ALL, border = 15)
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.OnDragInit)
self.DropTarget = TextDropTargetListCtrl(self.listctrl_right, self)
self.GridBagSizer.AddGrowableCol(0)
self.GridBagSizer.AddGrowableCol(1)
self.GridBagSizer.AddGrowableRow(0)
self.SetSizer(self.GridBagSizer)
# def OnHoverEnter(self, event):
# self.hovering = True
# def OnHoverLeave(self, event):
# self.hovering = False
def OnDragInit(self, evt):
text = self.listctrl_left.GetItemText(evt.GetIndex())
tdo = wx.TextDataObject(text)
tds = wx.DropSource(self.listctrl_left)
tds.SetData(tdo)
tds.DoDragDrop(True)
# evt.Skip()
if __name__ == "__main__":
app = wx.App()
MainFrame = MainApp()
MainFrame.Show()
MainFrame.Centre()
app.MainLoop()
这非常骇人听闻,但可以做你想做的事...最初我尝试了 EVT_ENTER_WINDOW
和 EVT_LEAVE_WINDOW
事件,它们在 listctrl 上运行正常,但 在拖动时没有运行 [=16] =].所以,我只是检查了 drop 事件的 x 坐标是否落在正确的 listctrl 小部件内。