wxpython拖放:仅当光标位于目标列表ctrl obj内时才进行拖放

2024-06-28 11:12:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用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()

Tags: 对象文本selfright目标objectinitstyle
1条回答
网友
1楼 · 发布于 2024-06-28 11:12:29
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_WINDOWEVT_LEAVE_WINDOW事件,这两个事件在listcrl上正常工作,但是在拖动时效果不是很好。所以,我只是检查了drop事件的x坐标是否在右边的listcrl小部件中。在

相关问题 更多 >