wxpython树形控件中使用拖放功能
import wx
class MyTextDropTarget(wx.TextDropTarget):
def __init__(self, obj):
super().__init__()
self.object = obj
self.target_item = wx.TreeItemId()
def OnDropText(self, x, y, data) -> bool:
point = wx.Point(x, y)
item, flags = self.object.HitTest(point)
if item.IsOk():
self.target_item = item # 获取目标item
return True
class MyTree(wx.TreeCtrl):
def __init__(self, parent):
super().__init__(parent)
self.text = ''
self.dragged_item = None
self.dt = MyTextDropTarget(self)
self.SetDropTarget(self.dt)
self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.on_begin_drag)
self.Bind(wx.EVT_TREE_END_DRAG, self.on_end_drag)
def on_begin_drag(self, event):
self.dragged_item = event.GetItem()
item_id = self.GetItemData(self.dragged_item)['编号']
if item_id == 0:
return # 根目录不能移动
self.text = self.GetItemText(self.dragged_item)
tdo = wx.TextDataObject(self.text)
tds = wx.DropSource(self)
tds.SetData(tdo)
drag_result = tds.DoDragDrop(True)
if drag_result != 1:
if self.GetItemData(self.dragged_item) != self.GetItemData(self.dt.target_item): # 原项目与目标项目不同
self.on_end_drag(event)
def on_end_drag(self, _):
target = self.dt.target_item
parent_id = self.GetItemData(target)['编号']
item_data = self.GetItemData(self.dragged_item).copy()
item_data['父项编号'] = parent_id
new_item = self.AppendItem(target, self.text, data=item_data)
self.insert_children(self.dragged_item, new_item)
self.SelectItem(target)
self.ExpandAllChildren(target)
self.Delete(self.dragged_item)
# 通过递归方法,移动所有原项目(parent)下的子项到目标项(target)
def insert_children(self, parent: wx.TreeItemId, target: wx.TreeItemId):
child, cookie = self.GetFirstChild(parent)
if child.IsOk():
item_data = self.GetItemData(child)
new = self.AppendItem(target, self.GetItemText(child), data=item_data)
self.insert_children(child, new)
while True:
child, cookie = self.GetNextChild(parent, cookie)
if child.IsOk():
item_data = self.GetItemData(child)
new = self.AppendItem(target, self.GetItemText(child), data=item_data)
self.insert_children(child, new)
else:
break
else:
return False
class Frame(wx.Frame):
def __init__(self):
super().__init__(None, title="MyTree", size=(600, 400))
font = wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "微软雅黑")
self.SetFont(font)
def make_data():
col_names = ['编号', '名称', '描述', '父项编号', 'ABC分类']
row_datas =[(1001, '电动自行车', '', 1019, 'A'),
(1003, '车辆配件', '', 1019, 'B'),
(1011, '维修配件', '', 1003, 'B'),
(1012, '改装配件', '', 1003, 'B'),
(1013, '其他配件', '', 1003, 'B'),
(1019, '产品', '实物产品', 0, ''),
(1020, '服务', '人工服务', 0, ''),
(1021, '防护用品', '', 1019, 'B'),
(1022, '其它产品', '', 1019, 'C'),
(1023, '维修服务', '', 1020, ''),
(1024, '改装服务', '', 1020, ''),
(1025, '其它服务', '', 1020, '')]
my_data = []
for d in row_datas:
my_data.append(dict(zip(col_names, d)))
return my_data
tree_data = make_data()
panel = wx.Panel(self)
tree = MyTree(panel)
root = tree.AddRoot("根目录", data={'编号': 0})
def insert_children(parent, item_datas):
rows = [row for row in item_datas if row['父项编号'] == tree.GetItemData(parent)['编号']]
if rows:
for row in rows:
new_item = tree.AppendItem(parent, row['名称'], data=row)
insert_children(new_item, item_datas)
# if row['父项编号'] == 0: # 展开一级目录
# (new_item)
insert_children(root, tree_data)
tree.Expand(root)
box = wx.BoxSizer()
box.Add(tree, 1, wx.EXPAND)
panel.SetSizerAndFit(box)
if __name__ == '__main__':
app = wx.App()
frame = Frame()
frame.Center()
frame.Show()
app.MainLoop()