wxPython CustomTreeCtrl树控件拖放到其他控件和树自身节点一览

拖放参考文章:https://blog.csdn.net/u012999796/article/details/54139496

CustomTreeCtrl是一个wxpython的树控件类,在使用的过程中对于拖放功能一直不是很理解,最近看了以上文章和参考了一些其他例子的代码,对于wxPython实现该功能做一些说明。

内容

首先创建一个基础的界面,含有两个树CustomTreeCtrl和一个文本框TextCtrl。

class Windows(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, id=-1, name='IDEFrame',\
        	parent=parent, pos=wx.DefaultPosition, size=wx.Size(1000, 600),\
        	style=wx.DEFAULT_FRAME_STYLE)
        self.SetClientSize(wx.Size(1000, 600))
        bpanel = wx.Panel(self)
        self.tree1 = CT.CustomTreeCtrl(bpanel,
              size=wx.Size(300, 550),  
              style=wx.SUNKEN_BORDER,
                  agwStyle=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.TR_EDIT_LABELS|wx.TR_FULL_ROW_HIGHLIGHT|wx.TR_HAS_VARIABLE_ROW_HEIGHT)
        self.tree2 = CT.CustomTreeCtrl(bpanel,
              size=wx.Size(300, 550),  
              style=wx.SUNKEN_BORDER,
                  agwStyle=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.TR_EDIT_LABELS|wx.TR_FULL_ROW_HIGHLIGHT|wx.TR_HAS_VARIABLE_ROW_HEIGHT)
        self.text1 = wx.TextCtrl(id=-1,name='showtext', parent=bpanel,\
        	size=wx.Size(400, 550), style=wx.TE_MULTILINE)


        hbox = wx.BoxSizer(wx.HORIZONTAL)
        hbox.Add(self.tree1,0,flag=wx.LEFT,border=5)
        hbox.Add(self.tree2,0,flag=wx.LEFT,border=5)
        hbox.Add(self.text1,1,flag=wx.LEFT,border=5)
        bpanel.SetSizer(hbox)

添加其树的简单节点:

    def addDataToTree(self):
        list1 = ["aaa","bbb","ccc"]
        list2 = ["qqq","www","eee"]
        root1 = self.tree1.AddRoot("tree1")
        root2 = self.tree2.AddRoot("tree2")
        for i in list1:
            item1 = self.tree1.AppendItem(root1,i)
            self.tree1.SetPyData(item1, {"type" : "Node","Name":i})
        for i in list2:
            item1 = self.tree2.AppendItem(root2,i)
            self.tree2.SetPyData(item1, {"type" : "Node","Name":i})

实现三种拖放:

树节点内容拖放到文本框进行显示节点名称等;

树节点自己拖放到自己上完成分类;

两个树互相拖放。 (如果只是简单拖放,和文本框一样)

树节点到文本框的拖放:

效果图:

wxPython CustomTreeCtrl树控件拖放到其他控件和树自身节点一览_第1张图片

绑定处理树的拖放事件:

self.tree1.Bind(wx.EVT_TREE_BEGIN_DRAG, self.sendData1)
    def sendData1(self,event):
        selected_item = event.GetItem()
        item_pydata = self.tree1.GetPyData(selected_item)
        
        if item_pydata is not None and item_pydata["type"] == "Node":
            data = wx.TextDataObject(str(
                (self.tree1.GetItemText(selected_item), 
                 item_pydata["type"], 
                 item_pydata["Name"])))
            dragSource = wx.DropSource(self.tree1)
            dragSource.SetData(data)
            dragSource.DoDragDrop()

这样就将树的发送任务完成。接着添加文本框的接收任务功能:

首先创建一个类:

class textDropTarget(wx.TextDropTarget):
    """docstring for treeDropTarget"""
    def __init__(self, parent):
        super(textDropTarget, self).__init__()
        self.parent = parent
    def OnDropText(self,x,y,data):# (rect:x,y,width,height)
        try:
            values = eval(data)
            self.parent.write(values[0]) #(name,type)
        except:
            return

然后文本框添加该类的实例即可: 

        #添加文本框的接收功能
        textdrop = textDropTarget(self.text1)
        self.text1.SetDropTarget(textdrop)

两个树互相拖放:

wxPython CustomTreeCtrl树控件拖放到其他控件和树自身节点一览_第2张图片

创建一个类用于给到树的接收拖放功能:

#互相拖放
class treeDropTarget2(wx.TextDropTarget):
    def __init__(self, parent):
        super(treeDropTarget2, self).__init__()
        self.parent = parent
        self.tree = None
    def setTree(self,tree):
        self.tree = tree
    def OnDropText(self,x,y,data):# (rect:x,y,width,height)
        try:
            values = eval(data)
            root = self.tree.GetRootItem()
            item1 = self.tree.AppendItem(root,values[0])
            self.tree.SetPyData(item1, {"type" : "Node","Name":values[0]})
        except:
            return

 然后添加其功能:

        #相互拖放:
        dop1 = treeDropTarget2(self)
        dop1.setTree(self.tree1)
        self.tree1.SetDropTarget(dop1)
        dop2 = treeDropTarget2(self)
        dop2.setTree(self.tree2)
        self.tree2.SetDropTarget(dop2)

树节点自己拖放到自己上完成分类:

分类拖放这里没有提供全部代码,但是框架是有的。可以看出已经成功定位其分类的父节点,接着只要进行细化处理即可:

wxPython CustomTreeCtrl树控件拖放到其他控件和树自身节点一览_第3张图片

首先完成一个简单的迭代来处理树的复杂结构字典的刷新函数。

    def refreshtreehandle(self,tree,lists):
        for i in sorted(lists):
            if type(lists[i]) == dict:
                item1 = self.tree1.AppendItem(tree,i)
                self.tree1.SetPyData(item1, {"type" : "Root","Name":i})
                self.refreshtreehandle(item1,lists[i])
            else:
                item1 = self.tree1.AppendItem(tree,i)
                self.tree1.SetPyData(item1, {"type" : "Node","Name":i})

    def refreshtree1(self):
        self.tree1.DeleteAllItems()
        root = self.tree1.AddRoot("tree1")
        self.refreshtreehandle(root,self.treelist)

然后就可以在初始化的时候进行刷新:

        self.treelist = {"A":{"B":"Node","C":"Node"},"AS":{"WWW":{"QQQ":"Node"}},"B":"Node","B1":"Node",\
                        "B2":"Node","B3":"Node","B4":"Node","B5":"Node","B6":"Node","B7":"Node"}
        self.refreshtree1()

接着定义一个关于分类拖放的类定义:

#分类拖放
class treeDropTarget1(wx.TextDropTarget):
    def __init__(self, parent):
        super(treeDropTarget1, self).__init__()
        self.parent = parent
        self.tree = None

    def setTree(self,tree):
        self.tree = tree

    #获取节点
    def GetTreeItemsByXY(self,DebugTree,root,x,y):
        (item,cookie) = DebugTree.GetFirstChild(root)
        while item != None:
            ix,iy,iw,ih = self.tree.GetBoundingRect(item)
            if y >= iy and y <= (iy+ih) and self.tree.IsVisible(item):
                return item
            if DebugTree.GetChildrenCount(item) > 0:
                retitem = self.GetTreeItemsByXY(DebugTree,item,x,y)
                if retitem != None:
                    return retitem
            else:
                pass
            (item,cookie) = DebugTree.GetNextChild(root,cookie)
        return None

    def OnDropText(self,x,y,data):# (x,y) DropData (rect:x,y,width,height)
        try:
            values = eval(data)
        except:
            return
        root = self.tree.GetRootItem()
        item = self.GetTreeItemsByXY(self.tree,root,x,y)#根据坐标获取节点
        if item != None:
            ret = self.tree.GetPyData(item)
            print ret
            if ret["type"] == "Node" or values[1] == "Root":
                return
            else:
                #删除原来的:self.treelist
                #添加到新的根上:self.treelist
                #刷新 :def refreshtree1
                pass

进入导入即可:

        dop = treeDropTarget1(self)
        dop.setTree(self.tree1)
        self.tree1.SetDropTarget(dop)

源码:https://download.csdn.net/download/qq_37887537/11573669

你可能感兴趣的:(wxpython)