2016-06-01 31 views
0

wxpythonを使用して小さなアプリケーションを作成しようとしています。listctrlオブジェクト(ソース)からテキストをドラッグして別のlistctrlオブジェクト(ターゲット)。wxpythonドラッグアンドドロップ:カーソルがターゲットの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() 
+0

は 'wx.EVT_SET_FOCUS'をキャッチし、これをフラグに格納し、このフラグを' OnDropText'でチェックすることができますか? cf. http://stackoverflow.com/questions/25899489/how-to-write-wxpython-textctrl-focus-event – otterb

+0

'TextDropTargetListCtrl :: OnDropText'がカーソルが' listctrl_right'を超えていなくても実行されるということですか?どうしたらこの問題が起こるのか分かりません。問題の説明を誤解しているかもしれません。 –

+0

@ VZ。それはまさに何が起こっているのかです。 – Alex

答えて

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

これはをドラッグしながら当初、私はlistctrlで[OK]を働いたEVT_ENTER_WINDOWEVT_LEAVE_WINDOWイベントを試みたが、ない...非常にハックですが、あなたが望むん。ですから、dropイベントのx座標が正しいlistctrlウィジェット内にあるかどうかを確認しました。

+0

ありがとう!これは完全に機能します。 – Alex

関連する問題