You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用类创建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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:33:18