NiceGUI中下拉选框与输入值绑定并更新表格行内容问题
问题分析
你的代码存在三个核心问题导致表格无法同步更新:
- 直接赋值组件的
.value只是一次性获取初始值,后续用户修改输入框/下拉框时,变化不会同步到programheader实例的属性中。 - 可刷新表格
ph_table_refreshable初始化时只接收了一次静态数据,刷新时没有重新从programheader获取最新状态。 - 按钮的
on_click参数错误地直接执行了ph_table_refreshable.refresh(),导致程序启动时就触发刷新,而非点击按钮时执行。
解决方案
通过三个关键修改实现数据同步:
- 用NiceGUI的
bind_value_to建立UI组件与类属性的双向绑定,确保用户操作自动同步到类实例。 - 修改可刷新表格函数,让它直接从
programheader实例动态获取数据,每次刷新都拿到最新状态。 - 修复按钮点击回调,用匿名函数包裹刷新方法,确保点击时才触发。
修改后的完整代码
app.py
from nicegui import ui from sequences import ProgramHeader # 假设machines是已定义的选项列表 machines = ['Machine A', 'Machine B', 'Machine C'] # 可刷新表格:直接从实例获取最新数据 @ui.refreshable def ph_table_refreshable(program_header_instance): columns, rows = program_header_instance.get_table_data ui.table(columns=columns, rows=rows, row_key='attribute') # Tab设置 with ui.tabs() as tabs: ui.tab('Program Header') programheader = ProgramHeader() with ui.tab_panels(tabs): with ui.tab_panel('Program Header'): with ui.row().classes('w-full'): with ui.column(): # 用bind_value_to替代直接赋值,建立双向绑定 ui.number(label="Operation ID", min=0, value=0).bind_value_to(programheader, 'op_id') ui.select(label="Machine Name", options=machines).bind_value_to(programheader, 'machine_name') ui.input(label="Print Reference").bind_value_to(programheader, 'print_reference') ui.number(label="Number of Operations", value=2).bind_value_to(programheader, 'num_operations') with ui.column(): ui.label("Program Header Properties") # 传入实例,让表格每次刷新都获取最新数据 ph_table_refreshable(programheader) # 修复回调:点击时才执行刷新 ui.button("Update", on_click=lambda: ph_table_refreshable.refresh()) ui.run()
sequences.py(可选优化)
from datetime import datetime class ProgramHeader: def __init__( self, op_id: int = 0, machine_name: str = '', print_reference: str = '', num_operations: int = 2, operation_notes: str = None, choice: str = 'active', up_to_date: str = None ): # 输入变量 self.op_id = op_id self.machine_name = machine_name self.print_reference = print_reference self.num_operations = num_operations # 非输入变量 self.operation_notes = "" if not operation_notes else f" - {operation_notes}" self.choice = choice.upper() self.up_to_date = up_to_date self.date = datetime.now().date() self.total_date = f"{self.date} AND UP" if not self.up_to_date else f"{self.date} UP THROUGH {self.up_to_date}" @property def get_table_data(self): columns = [ {'name': 'attribute', 'label': 'Attribute', 'field': 'attribute', 'required': True, 'align': 'left'}, {'name': 'value', 'label': 'Value', 'field': 'value'} ] # 可选:过滤掉不需要展示的内部属性,只显示关键字段 display_attrs = ['op_id', 'machine_name', 'print_reference', 'num_operations', 'operation_notes', 'choice', 'total_date'] rows = [{'attribute': k, 'value': v} for k, v in self.__dict__.items() if k in display_attrs] return columns, rows
额外优化:自动刷新表格
如果不需要手动点击按钮,希望修改输入时表格自动更新,可以给每个组件添加on_change事件:
ui.number(label="Operation ID", min=0, value=0)\ .bind_value_to(programheader, 'op_id')\ .on_change(lambda e: ph_table_refreshable.refresh())
重复此逻辑到所有输入组件即可实现实时同步。
内容的提问来源于stack exchange,提问作者cjk5642
相关产品推荐
相关产品推荐

