Python读取Arduino数据时tkinter GUI运行后串口无响应问题求助
问题成因
- Tkinter事件循环阻塞:
win.mainloop()是Tkinter的阻塞式主事件循环,调用后程序会停在该行持续处理GUI重绘、交互等事件,只有窗口关闭后才会继续执行后续代码。你写的串口读取逻辑仅会在窗口启动前执行一次,进入mainloop后完全停止运行,自然无法读取Arduino返回数据,若串口逻辑出现阻塞还会直接导致GUI无响应。 - 逻辑顺序错误:你将串口读取逻辑放在了
mainloop()之前,且外部的while True循环完全被mainloop()阻断,无法循环执行串口读取操作。 - 代码逻辑bug:
data变量定义在while ser.in_waiting内部,若启动时无串口数据,后续if(bytes(data)=="solar1low")会直接触发未定义变量报错;且已解码的字符串转bytes时未指定编码,判断逻辑本身也无法正确匹配串口返回内容。 - 窗口实例错误:同时创建多个
Tk()主窗口实例(win和win2)会导致Tkinter资源管理混乱,次级窗口应使用Toplevel实现。
修复方案
使用Tkinter内置的after()方法实现非阻塞的串口定时读取,避免阻塞主事件循环,参考简化实现逻辑:
import serial import tkinter as tk from PIL import Image, ImageTk COM_PORT = 'COM7' BAUD_RATES = 9600 ser = serial.Serial(COM_PORT, BAUD_RATES) def read_serial(): # 定时读取串口数据 while ser.in_waiting: data_raw = ser.readline() data = data_raw.decode().strip() print('接收到的資料:', data) if data == "solar1low": show_food_window() # 100ms后再次调用自身读取串口 win.after(100, read_serial) def show_food_window(): # 次级窗口用Toplevel不要用新的Tk win2 = tk.Toplevel(win) win2.title("點餐系統") win2.geometry("1540x1050") # 这里放你的餐点页面控件逻辑 image3 = Image.open("D:\PYTHON\PROJECT\雙層吉事堡.png") 雙層吉事堡 = ImageTk.PhotoImage(image3) labelnext1 = tk.Label(win2, image=雙層吉事堡) labelnext1.image = 雙層吉事堡 labelnext1.config(width=650, height=650) labelnext1.place(x=450, y=100) # 其他控件省略 # 主窗口初始化只执行一次,不要放在while True里 win = tk.Tk() win.title("點餐系統") win.geometry("1540x1050") win.maxsize(width=1520, height=1050) # 主页面控件初始化 img3 = tk.PhotoImage(file="D:\PYTHON\PROJECT\雙層吉事堡.png") btn = tk.Button(win, text="雙層吉事堡", width=400, height=300, image=img3) btn.place(x=300, y=480) lb3 = tk.Label(win, fg="black", text="三號餐", font='30') lb3.place(x=475, y=450) # 启动串口定时读取 read_serial() win.mainloop()
内容的提问来源于stack exchange,提问作者方耀廷
相关产品推荐
相关产品推荐

