使用类创建ft.DragTarget时拖拽批量响应异常的解决问询
问题描述
我有3个拖拽目标(drag target)和1个可拖拽元素(draggable):
- 用for循环直接创建3个拖拽目标时,功能正常:将红色容器拖拽到任意黄色容器上方,
drag_accept事件会正确触发(创建按钮并更改背景色),代码如下:
def main(page: ft.Page): column = ft.Column(scroll=True) for i in range(0,3): column.controls.append(ft.DragTarget(content=ft.Container(bgcolor=ft.colors.AMBER, width=100, height=100), group='player', on_accept=target.drag_accept)) text1= ft.Text(value='CODE 1', size=50, color=ft.colors.BLUE) page.add(ft.Row(controls=[column, draggable(), text1]) )
- 但用类封装创建拖拽目标时,拖拽操作会同时影响全部3个目标,而非仅被拖拽到的那个,代码如下:
class target(ft.Container): def drag_accept(e): src = e.page.get_control(e.src_id) print(e.src_id) # print(e.control.content) e.control.content.bgcolor = ft.colors.PURPLE_100 e.control.content.content = delete_button(e.src_id) e.control.content.data = e.src_id e.control.update() drag_target = ft.DragTarget(group = 'player', content=ft.Container(), on_accept=drag_accept) def __init__(self): super().__init__() self.width = 100 self.height = 100 self.bgcolor = ft.colors.AMBER self.content = target.drag_target def cretate_target(n:int): a = [] for i in range(0,n): a.append(target()) return a def main(page: ft.Page): text2 =ft.Text(value='CODE 2', size=50, color=ft.colors.BLUE) for i in target.cretate_target(3): page.add(i) page.add(draggable(), text2)
请问如何让第二种创建方式的效果与第一种一致?
问题原因
你的target类中,drag_target是类属性,所有target实例都会共享同一个DragTarget对象。这意味着当任意一个实例触发drag_accept事件时,修改的是这个共享的DragTarget内容,导致所有实例的显示都跟着变化。
解决方案
把DragTarget的创建放到__init__方法内部,让每个target实例拥有独立的DragTarget对象;同时调整drag_accept的逻辑,确保只修改当前触发事件的控件内容。
修正后的代码如下:
class Target(ft.Container): # 类名遵循Python大驼峰命名规范 def drag_accept(e): # e.control 指向当前触发事件的DragTarget实例 src = e.page.get_control(e.src_id) print(e.src_id) # 修改当前DragTarget内部的Container属性 e.control.content.bgcolor = ft.colors.PURPLE_100 e.control.content.content = delete_button(e.src_id) e.control.content.data = e.src_id e.control.update() def __init__(self): super().__init__() self.width = 100 self.height = 100 self.bgcolor = ft.colors.AMBER # 每个实例独立创建DragTarget,避免共享 self.content = ft.DragTarget( group='player', content=ft.Container(bgcolor=ft.colors.AMBER, width=100, height=100), on_accept=Target.drag_accept ) @staticmethod def create_target(n: int): # 修正拼写错误:cretate -> create a = [] for i in range(n): a.append(Target()) return a def main(page: ft.Page): text2 = ft.Text(value='CODE 2', size=50, color=ft.colors.BLUE) for i in Target.create_target(3): page.add(i) page.add(draggable(), text2)
关键修改点
- 将
drag_target类属性移到__init__方法中,每个实例独立生成DragTarget,彻底避免共享实例的问题 - 修正类名、方法名的拼写和命名规范,提升代码可读性
- 确保
DragTarget的初始content与第一种创建方式一致,保持初始视觉效果统一
内容的提问来源于stack exchange,提问作者CronosVirus00
相关产品推荐
相关产品推荐

