2016-06-01 14 views
0

Ich versuche, eine kleine app erstellen wxpython mit dem ein Benutzer einen Text aus einem listctrl Objekt ziehen (die Quelle) und legen Sie es in einem anderen listctrl Objekt (das Ziel).wxpython Drag & Drop: fallen nur dann, wenn sich der Cursor in das Ziel ist ListCtrl Objekt

Ich möchte diese App so schreiben, dass eine Textzeichenfolge in das Ziel listctrl Objekt fallen gelassen wird nur, wenn der Cursor im Ziel listctrl Bereich. Mein Code (siehe unten) wird jetzt eine Textzeichenfolge löschen, auch wenn der Cursor sich nie in den Zielbereich bewegt. Jeder Zeiger würde sehr geschätzt werden!

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

vielleicht fangen 'wx.EVT_SET_FOCUS' und speichern Sie dies in einem Flag und überprüfen Sie dieses Flag in' OnDropText'? vgl. http://stackoverflow.com/questions/25899489/how-to-write-wxpython-textctrl-focus-event – otterb

+0

Meinst du, dass Ihre 'TextDropTargetListCtrl :: OnDropText' ausgeführt wird, auch wenn der Cursor nicht über' listctrl_right' ist? Ich habe Probleme zu sehen, wie das passieren könnte, vielleicht habe ich die Problembeschreibung missverstanden? –

+0

@ VZ. Genau das passiert. – Alex

Antwort

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

Das ist sehr hackish aber tut, was Sie wollen ... Am Anfang habe ich versucht, EVT_ENTER_WINDOW und EVT_LEAVE_WINDOW Ereignisse, die auf ListCtrl ok gearbeitet, aber während nicht ziehen. Also, ich habe gerade überprüft, ob die x-Koordinate des Drop-Ereignisses in das richtige Listctrl-Widget fällt oder nicht.

+0

Danke! Das funktioniert perfekt. – Alex