拖放参考文章: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})
实现三种拖放:
树节点内容拖放到文本框进行显示节点名称等;
树节点自己拖放到自己上完成分类;
两个树互相拖放。 (如果只是简单拖放,和文本框一样)
效果图:
绑定处理树的拖放事件:
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)
创建一个类用于给到树的接收拖放功能:
#互相拖放
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)
分类拖放这里没有提供全部代码,但是框架是有的。可以看出已经成功定位其分类的父节点,接着只要进行细化处理即可:
首先完成一个简单的迭代来处理树的复杂结构字典的刷新函数。
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