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

NiceGUI表格:如何实现行点击与选中事件并获取行数据

解决NiceGUI表格行点击获取数据的问题

你的代码存在两个核心问题:

  1. 自定义body插槽完全替换了默认表格结构,导致默认的选择复选框被移除。
  2. Vue的row-click事件没有正确传递到Python端,需要通过$emit将行数据发送给NiceGUI的事件处理器。

下面提供两种解决方案,根据你的需求选择:


方案一:保留选择复选框 + 支持行点击

如果需要同时保留选择复选框和行点击功能,需要在自定义插槽中手动添加选择列的单元格,并通过$emit触发Python端的事件:

from nicegui import ui

columns = [
    {'name': 'title', 'label': 'Title', 'field':'title', 'required': True, 'align': 'left'},
    {'name': 'author', 'label': 'Author', 'field':'author', 'align': 'left'},
    {'name': 'year', 'label': 'Year', 'field':'year', 'sortable': True, 'align': 'left'},
]

rows = [
    {'title': 'Some title A', 'url' : 'https://example.com/search?q=A', 'author': 'Alice', 'year': 2023},
    {'title': 'Some title B', 'url' : 'https://example.com/search?q=B', 'author': 'Bob', 'year': 2022},
    {'title': 'Some title C', 'url' : 'https://example.com/search?q=C', 'author': 'Carol', 'year': 2021}
]

def handle_row_click(row_data):
    print('点击的行数据:', row_data)
    ui.notify(f'点击了《{row_data["title"]}》')

table = ui.table(
    title='Example table',
    columns=columns,
    rows=rows,
    row_key='title',  # row_key需对应行数据中唯一字段,原代码的name字段不存在,改为title更合适
    pagination=5,
    selection='single',
    on_select=lambda e: ui.notify(f'选中的行: {e.selection}')
)
# 自定义body插槽,添加选择列+行点击事件
table.add_slot('body', r'''
    <q-tr :props="props" @click="$emit('row-click', props.row)">
        <!-- 手动添加选择复选框的列 -->
        <q-td auto-width>
            <q-checkbox v-model="props.selected" />
        </q-td>
        <q-td>
            <a :href="props.row.url">{{ props.row.title }}</a>
        </q-td>
        <q-td>{{ props.row.author }}</q-td>
        <q-td>{{ props.row.year }}</q-td>
    </q-tr>
''')
# 绑定row-click事件到Python处理器
table.on('row-click', handle_row_click)

ui.run()

方案二:仅行点击(无需复选框)

如果只需要行点击功能,不需要选择复选框,可以简化代码,去掉selection参数,直接绑定点击事件:

from nicegui import ui

columns = [
    {'name': 'title', 'label': 'Title', 'field':'title', 'required': True, 'align': 'left'},
    {'name': 'author', 'label': 'Author', 'field':'author', 'align': 'left'},
    {'name': 'year', 'label': 'Year', 'field':'year', 'sortable': True, 'align': 'left'},
]

rows = [
    {'title': 'Some title A', 'url' : 'https://example.com/search?q=A', 'author': 'Alice', 'year': 2023},
    {'title': 'Some title B', 'url' : 'https://example.com/search?q=B', 'author': 'Bob', 'year': 2022},
    {'title': 'Some title C', 'url' : 'https://example.com/search?q=C', 'author': 'Carol', 'year': 2021}
]

def handle_row_click(row_data):
    print('点击的行数据:', row_data)
    ui.notify(f'点击了《{row_data["title"]}》')

table = ui.table(
    title='Example table',
    columns=columns,
    rows=rows,
    row_key='title',
    pagination=5
)
# 自定义body插槽,绑定点击事件并传递行数据
table.add_slot('body', r'''
    <q-tr :props="props" @click="$emit('row-click', props.row)">
        <q-td>
            <a :href="props.row.url">{{ props.row.title }}</a>
        </q-td>
        <q-td>{{ props.row.author }}</q-td>
        <q-td>{{ props.row.year }}</q-td>
    </q-tr>
''')
table.on('row-click', handle_row_click)

ui.run()

关键说明:

  • row_key必须对应行数据中唯一标识的字段,原代码用name是错误的(行数据里没有该字段),改成title更合适。
  • 通过Vue的$emit('row-click', props.row)将行数据发送到Python端,再用table.on('row-click', handler)接收处理。
  • 如果保留选择功能,必须手动在插槽中添加复选框的q-td,否则默认选择列会被自定义插槽覆盖。

内容的提问来源于stack exchange,提问作者mikeiavelli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 00:10:59