wxpython树形控件中使用拖放功能

时间:2024-11-18 17:49:28
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()