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

NiceGui树形组件切换按钮数据未更新、事件未触发问题

NiceGui树形组件切换按钮无法触发事件且数据不更新问题排查

问题代码

from nicegui import events, ui

def toggleUpdate(e: events.GenericEventArguments) -> None:
    print(tree._props['nodes'])

tree = ui.tree([
    {'id': 'numbers', 'description': 'Just some numbers', 'update': True, 'children': [
    {'id': '1', 'description': 'The first number', 'update': False},
    {'id': '2', 'description': 'The second number', 'update': True},
]},
{'id': 'letters', 'description': 'Some latin letters', 'update': True, 'children': [
    {'id': 'A', 'description': 'The first letter', 'update': True},
    {'id': 'B', 'description': 'The second letter', 'update': True},
]},
], label_key='id', on_select=lambda e: ui.notify(e.value))

tree.add_slot('default-header', '''
<span :props="props">Node <strong>{{ props.node.id }}</strong></span>
''')
tree.add_slot('default-body', r'''
<span :props="props">Description: "{{ props.node.description }}"             <q-toggle
    v-model="props.node.update"
    label="Elemente updaten"
    left-label
    @update:model-value="() => $parent.$emit('toggleUpdate', props.node)"
/></span>
''')

ui.button("Test", on_click=lambda: toggleUpdate("TEST"))
tree.on('toggleUpdate', toggleUpdate)
tree.on('update:model-value', lambda e: ui.notify(e.args))

ui.run()

当前树形组件可正常显示,但点击切换按钮后数据未发生变更,且toggleUpdate事件未被触发。

错误原因及修正方案

1. 事件触发目标错误

在Vue插槽的q-toggle中使用$parent.$emit无法正确将事件传递到Python端的tree组件。NiceGui的组件事件需要直接通过$emit触发,不需要指定$parent。

2. 数据同步问题

直接修改props.node.update属于单向修改Vue端数据,不会同步回Python端的数据源。需要通过事件将更新后的状态传递回Python,手动更新数据源后刷新组件。

修正后的代码

from nicegui import events, ui

# 递归查找树形节点
def find_node(nodes, target_id):
    for node in nodes:
        if node['id'] == target_id:
            return node
        if 'children' in node:
            found = find_node(node['children'], target_id)
            if found:
                return found
    return None

def toggleUpdate(e: events.GenericEventArguments) -> None:
    node_id, new_state = e.args
    # 找到对应节点并更新状态
    node = find_node(tree_nodes, node_id)
    if node:
        node['update'] = new_state
        # 刷新树形组件
        tree.update()
    # 打印更新后的数据源
    print(tree_nodes)

# 把数据源存为变量,方便后续修改
tree_nodes = [
    {'id': 'numbers', 'description': 'Just some numbers', 'update': True, 'children': [
        {'id': '1', 'description': 'The first number', 'update': False},
        {'id': '2', 'description': 'The second number', 'update': True},
    ]},
    {'id': 'letters', 'description': 'Some latin letters', 'update': True, 'children': [
        {'id': 'A', 'description': 'The first letter', 'update': True},
        {'id': 'B', 'description': 'The second letter', 'update': True},
    ]},
]

tree = ui.tree(tree_nodes, label_key='id', on_select=lambda e: ui.notify(e.value))

tree.add_slot('default-header', '''
<span :props="props">Node <strong>{{ props.node.id }}</strong></span>
''')
tree.add_slot('default-body', r'''
<span :props="props">
    Description: "{{ props.node.description }}"
    <q-toggle
        :model-value="props.node.update"
        label="Elemente updaten"
        left-label
        @update:model-value="(new_val) => $emit('toggleUpdate', props.node.id, new_val)"
    />
</span>
''')

ui.button("Test", on_click=lambda: print(tree_nodes))
tree.on('toggleUpdate', toggleUpdate)

ui.run()

关键修改点:

  • 将数据源提取为tree_nodes变量,便于Python端修改
  • 把q-toggle的v-model改为:model-value,避免直接修改props,通过@update:model-value触发事件传递节点ID和新状态
  • 实现find_node递归函数查找目标节点,更新后调用tree.update()刷新组件
  • 事件触发改为直接$emit('toggleUpdate', props.node.id, new_val),确保Python端能接收参数

内容的提问来源于stack exchange,提问作者otto.kranz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:04:53