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
相关产品推荐
相关产品推荐

