Taipy long_callback无法更新状态值问题排查求助
问题分析与解决
问题描述
基于Arduino的DAQ系统,使用Taipy的long_callback测试4×4矩阵键盘,通过两个状态按钮模拟Arduino模拟输入的高低状态。状态按钮的lov绑定keypad[1],关联变量为keypad_choice_1。添加「开始采集」和「重置屏幕至低值」按钮后,执行「高输入→启动→重置→低输入→再次启动」操作,屏幕状态未更新为低值,仍保留高值。status_DAQ函数已更新state变量,但on_DAQ调用时存在变量残留问题。
问题根源
- 全局变量
keypad_choice状态污染:on_DAQ直接修改全局的keypad_choice字典,重置操作仅修改state中的对应变量,但全局变量仍保留上一次高输入的修改值,导致后续调用时残留旧状态。 on_DAQ未基于当前状态初始化结果:每次调用on_DAQ时未从当前state的初始状态生成新结果,复用全局变量导致状态持续被污染。- 低输入逻辑未重置按键状态:当
value_tgg为Low时,模拟输入未触发按键检测,但函数未处理该场景,不会重置按键状态到初始值,因此保留高输入时的状态。
修复方案
- 移除全局变量依赖:
on_DAQ函数接收当前state的keypad_choice作为初始参数,基于该参数生成新结果,避免全局变量残留。 - 低输入时强制重置状态:在
value_tgg为Low的分支中,直接将按键状态重置为初始值,并退出循环,确保低输入状态生效。 - 修正回调参数传递:调用
invoke_long_callback时传入当前state的keypad_choice副本,保证每次调用基于最新状态。
修改后的代码
from taipy import Gui from taipy.gui import State, invoke_long_callback, notify import numpy as np import time import os keypad = {1:[('E', '1'), ('S', '1'), ('W', '1')],2:[('E', '2'), ('S', '2'), ('W', '2')]} keypad_choice_1 = keypad[1][0] keypad_choice_2 = keypad[2][0] keypad_choice = {1:keypad[1][0],2:keypad[2][0]} status = 0 value_tgg = 'High' test_time = 5 def on_reset(state): state.keypad_choice_1=state.keypad[1][0] state.keypad_choice_2=state.keypad[2][0] state.keypad_choice={1:state.keypad[1][0],2:state.keypad[2][0]} print('after reset click') print(state.keypad_choice_1) print(state.keypad_choice[1]) print('******') def on_action(state): notify(state, "info", "Heavy task started...") print('after start') print(state.keypad_choice_1) print(state.keypad_choice[1]) print('******') # 传入当前state的keypad_choice副本作为初始状态 invoke_long_callback(state,on_DAQ,[state.test_time,state.value_tgg, state.keypad_choice.copy()],status_DAQ,[],500) def status_DAQ(state,status,keypad_choice): notify(state, 'i', f"Status parameter: {status}") if isinstance(status, bool): if status: notify(state, 'success', "Finished") print('Notify: before finish') print(state.keypad_choice_1) print(state.keypad_choice[1]) state.keypad_choice_1= keypad_choice[1] state.keypad_choice_2= keypad_choice[2] state.keypad_choice = keypad_choice print('Notify: after finish and assign the new value') print(state.keypad_choice_1) print(state.keypad_choice[1]) print('******') state.status=0 else: notify(state, 'error', f"An error was raised") else: state.status += 1 def on_DAQ(test_time,value_tgg, initial_keypad_choice): # 使用传入的初始状态,避免依赖全局变量 keypad_choice = initial_keypad_choice.copy() i=0 starttime = time.time() while i<2: # 模拟Arduino模拟输入读取 if value_tgg == 'High': print('AI-high') C4=0. C3=0. C2=0. C1=0.22 L4=1 L3=1 L2=1 L1=0.5 else: print('AI -low') # 低输入时直接重置按键状态为初始值 keypad_choice = {1:keypad[1][0],2:keypad[2][0]} C4=0. C3=0. C2=0. C1=0. L4=1 L3=1 L2=1 L1=1 # 低输入无需继续检测,直接退出循环 break lin_Teclas = np.array([[C1, C2, C3, C4]]) col_Teclas=1-np.array([[L1,L2,L3,L4]]) Teclas=np.matmul(col_Teclas.T,lin_Teclas) indexPress=Teclas.nonzero() if indexPress[0].size == 0 : aux_valindexPress=0 else: valindexPress=4*indexPress[0]+indexPress[1]+1 aux_valindexPress=valindexPress[0].item() if aux_valindexPress==1 and i==0: keypad_choice[1]=keypad[aux_valindexPress][1] i+=1 elif aux_valindexPress==2 and i==1: keypad_choice[2]=keypad[aux_valindexPress][1] i+=1 aux_valindexPress=0 telaps=round((time.time()-starttime),2) if telaps >test_time: i=3 return keypad_choice page1_md= """ ## TEST number refresh notifications <|{status}|> #####Time for hard function <|layout|columns = 200px 200px 200px <| Time (seg) <|{test_time}|number|> |> |> <|{value_tgg}|toggle|lov=High;Low|> <| <center> | <|{keypad_choice_1}|status|lov={keypad[1]}|> | <|{keypad_choice_2}|status|lov={keypad[2]}|> | </center> |> <|START|button|on_action={on_action}|id=btn01|> <|RESET|button|on_action={on_reset}|id=btn01|> """ Gui(page1_md).run(use_reloader=True,port=50000)
内容的提问来源于stack exchange,提问作者Jaime Rodriguez
相关产品推荐
相关产品推荐

