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

Tkinter中持续变化模拟值的类型转换问题求助

问题:Tkinter中IntVar获取空值触发_tkinter.TclError

程序用Python Tkinter实现每100ms读取Modbus模拟值并显示,运行正常。但将模拟值转换为距离时,尝试从IntVar获取值并转整型时,得到空字符串而非数字,触发_tkinter.TclError。


核心代码

# set global
regs_x = []
regs_y = []
# init a thread lock
regs_lock_x = Lock()
regs_lock_y = Lock()

def polling_thread():
    global regs_x, regs_y, regs_lock_x, regs_lock_y
    c = ModbusClient(host='192.168.1.50', port=502, auto_open=True)
    while True:
        # do modbus reading on socket
        reg_list_x = c.read_holding_registers(0, 1)
        reg_list_y = c.read_holding_registers(1, 1)
        # if read is ok, store result in regs (with thread lock)
        if reg_list_x:
            with regs_lock_x:
                #regs_x = list(reg_list_x)
                regs_x = reg_list_x
        if reg_list_y:
            with regs_lock_y:
                regs_y = list(reg_list_y)
        # 1s before next polling
        #time.sleep(1)


def get_analog_x():
    # print regs list (with thread lock synchronization)
            with regs_lock_x:
                list_string_x = ''.join(map(str, regs_x))
                #print(list_string_x)
                analog_value_x.set(list_string_x)
            window.after(100, get_analog_x)

def get_analog_y():
    # print regs list (with thread lock synchronization)
            with regs_lock_y:
                list_string_y = ''.join(map(str, regs_y))
                #print("".join(list_string_x)
                analog_value_y.set(list_string_y)
            window.after(100, get_analog_y)

# start x polling thread
tp = Thread(target=polling_thread)
# set daemon: polling thread will exit if main thread exit
tp.daemon = True
tp.start()


analog_value_x = IntVar()
analog_value_y = StringVar()

get_analog_x()
get_analog_y()

显示控件代码

x_lvdt=Entry(window, width=5, justify=CENTER, font=('Arial 14'), textvariable=analog_value_x)

转换代码

int_x = analog_value_x.get()
print(int_x)
#print(int_x / 1290)

错误信息

int_x = analog_value_x.get()
  File "/usr/lib/python3.8/tkinter/__init__.py", line 547, in get
    return int(self._tk.getdouble(value))
_tkinter.TclError: expected floating-point number but got ""

解决方案

1. 初始化IntVar默认值

程序启动时regs_x是空列表,第一次执行get_analog_x()时,''.join(map(str, regs_x))会生成空字符串,而IntVar不允许设置空值。给analog_value_x设置初始默认值:

analog_value_x = IntVar(value=0)

2. 处理空列表的情况

在get_analog_x和get_analog_y中,先判断regs_x/regs_y是否为空,避免生成空字符串:

def get_analog_x():
    with regs_lock_x:
        if regs_x:
            list_string_x = ''.join(map(str, regs_x))
            analog_value_x.set(list_string_x)
        else:
            # 保持当前值或设置默认值
            pass
    window.after(100, get_analog_x)

3. 直接存储数值而非字符串

既然reg_list_x是Modbus读取的寄存器值(应为整数),直接把数值存入regs_x,而非后续转字符串:

# 全局变量初始化修改
regs_x = None
regs_y = None

# polling_thread中修改
if reg_list_x:
    with regs_lock_x:
        # 取第一个寄存器值,因为read_holding_registers返回列表
        regs_x = reg_list_x[0]

# get_analog_x修改
def get_analog_x():
    with regs_lock_x:
        if regs_x is not None:
            analog_value_x.set(regs_x)
        else:
            analog_value_x.set(0)
    window.after(100, get_analog_x)

4. 安全获取IntVar值

如果无法避免空值场景,获取值时先做异常捕获:

try:
    int_x = analog_value_x.get()
except _tkinter.TclError:
    int_x = 0  # 设置默认值或做其他处理
print(int_x)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:47:32