PySimpleGUI表格温度数据无法更新问题求助
问题分析与解决方案
你的代码存在几个关键问题导致表格无法更新:
核心问题点
- 窗口重复初始化:布局和窗口创建放在外层
while循环内,每次循环都会新建窗口,旧窗口未被正确销毁,数据更新无法作用到当前显示的窗口。 - 未触发定时事件:
window.read()未设置超时参数,永远不会触发TIMEOUT_EVENT,Modbus读取逻辑根本不会执行。 - 错误的更新目标:表格的key是
-TABLE-,但代码中尝试更新不存在的CLK元素。 - 表格更新方式错误:仅修改数据源变量
currentTemp不会自动同步到表格,必须调用Table组件的update()方法传入新数据。 - 串口频繁开关:每次读取都重新打开/关闭串口,不仅效率低,还可能引发串口占用问题。
修正后的代码
import PySimpleGUI as sg import time import serial # 初始化温度值 currentTemp = -99 # 初始化串口(仅打开一次) try: ComPort = serial.Serial("COM3", baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=1) except Exception as e: sg.popup_error(f"串口打开失败:{str(e)}") exit() # 定义表格数据和布局(仅初始化一次) data_array = [[currentTemp, 'empty']] headings = ['Temperature', 'Humidity'] layout = [ [sg.Table( values=data_array, headings=headings, max_col_width=35, auto_size_columns=True, display_row_numbers=True, justification='right', num_rows=10, key='-TABLE-', row_height=35 )] ] window = sg.Window("Temp_Humidity", layout) while True: # 设置1秒超时,触发定时更新 event, values = window.read(timeout=1000) if event == sg.WIN_CLOSED: break # 超时事件触发,执行Modbus读取和表格更新 if event == sg.TIMEOUT_EVENT: try: Temphex = b'\x01\x03\x00\x00\x00\x02\xC4\x0B' ComPort.write(Temphex) temp = ComPort.read(7) if len(temp) == 7: # 确保读取到完整数据 t = " ".join(["{:02x}".format(x) for x in temp]) t1 = int(t[9:11] + t[12:14], 16) / 100 # 修正切片索引,避免越界 tf = round((t1 * (9/5)) + 32, 2) print(tf) # 更新表格数据 data_array[0][0] = tf window['-TABLE-'].update(values=data_array) except Exception as e: print(f"读取数据出错:{str(e)}") # 关闭串口和窗口 ComPort.close() window.close()
关键修改说明
- 窗口与布局只初始化一次:将布局定义、窗口创建移到外层循环外,确保始终操作同一个窗口实例。
- 添加超时参数:
window.read(timeout=1000)让窗口每秒触发一次TIMEOUT_EVENT,实现定时更新。 - 正确更新表格:修改数据源
data_array后,调用window['-TABLE-'].update(values=data_array)刷新表格显示。 - 优化串口操作:程序启动时打开串口,关闭窗口时再关闭,避免频繁开关导致的问题。
- 数据完整性检查:添加
len(temp) == 7判断,确保读取到完整的Modbus响应数据,避免切片错误。 - 修正切片索引:原代码中
t[12:15]会取3个字符,导致拼接后的数据长度异常,改为t[12:14]取正确的2位十六进制数。
内容的提问来源于stack exchange,提问作者KurtA
相关产品推荐
相关产品推荐

