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

Taipy long_callback无法更新状态值问题排查求助

问题分析与解决

问题描述

基于Arduino的DAQ系统,使用Taipy的long_callback测试4×4矩阵键盘,通过两个状态按钮模拟Arduino模拟输入的高低状态。状态按钮的lov绑定keypad[1],关联变量为keypad_choice_1。添加「开始采集」和「重置屏幕至低值」按钮后,执行「高输入→启动→重置→低输入→再次启动」操作,屏幕状态未更新为低值,仍保留高值。status_DAQ函数已更新state变量,但on_DAQ调用时存在变量残留问题。

问题根源

  1. 全局变量keypad_choice状态污染:on_DAQ直接修改全局的keypad_choice字典,重置操作仅修改state中的对应变量,但全局变量仍保留上一次高输入的修改值,导致后续调用时残留旧状态。
  2. on_DAQ未基于当前状态初始化结果:每次调用on_DAQ时未从当前state的初始状态生成新结果,复用全局变量导致状态持续被污染。
  3. 低输入逻辑未重置按键状态:当value_tgg为Low时,模拟输入未触发按键检测,但函数未处理该场景,不会重置按键状态到初始值,因此保留高输入时的状态。

修复方案

  1. 移除全局变量依赖:on_DAQ函数接收当前state的keypad_choice作为初始参数,基于该参数生成新结果,避免全局变量残留。
  2. 低输入时强制重置状态:在value_tgg为Low的分支中,直接将按键状态重置为初始值,并退出循环,确保低输入状态生效。
  3. 修正回调参数传递:调用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:55:36