root.mainloop() 是阻塞式事件循環,其後代碼只有在窗口關閉後才會執行。
def on_send():
sock.send(data)
# 接收也在回調或 after 中
btn_send.config(command=on_send)
root.mainloop() # 只有這行在主線程
def check_recv():
try:
data = sock.recv(1024)
if data: txt.insert(END, data.decode())
except BlockingIOError: pass
root.after(100, check_recv) # 100ms 輪詢
check_recv()
root.mainloop()
def recv_loop():
while True:
data = sock.recv(1024)
if not data: break
root.after(0, lambda d=data: txt.insert(END, d.decode())) # 必須在主線程更新 UI
threading.Thread(target=recv_loop, daemon=True).start()
root.mainloop()
Tkinter 所有 UI 操作必須在主線程;耗時/阻塞操作放子線程,回調用
root.after(0, callback)切回主線程。