Tkinter与Socket集成时GUI冻结问题求助
问题原因
Tkinter的mainloop是单线程运行的,你的myClick函数里包含server.accept()和无限循环接收数据的阻塞操作,这些操作会占用主线程,导致GUI无法响应任何事件,直接冻结。
解决方案:用多线程分离Socket逻辑
把Socket的连接和数据接收逻辑放到子线程中执行,让主线程专注处理GUI事件。
修改后的服务器代码:
import socket from tkinter import * import threading # 引入线程模块 HOST='127.0.0.1' PORT=6595 root = Tk() root.title("Server") root.geometry("300x100") # 初始化Socket server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind((HOST,PORT)) server.listen() def receive_data(): # 子线程中处理Socket连接和接收 communication_socket, address = server.accept() while True: counter=communication_socket.recv(1024) if not counter: communication_socket.close() break counter=counter.decode('utf-8') # 更新Label内容 myLabel.config(text=f"Message from client is {counter}") def myClick(): # 点击按钮后启动子线程,不阻塞主线程 threading.Thread(target=receive_data, daemon=True).start() myButton = Button(root, text="Display the counter sent", command=myClick, padx=10, pady=5, fg="black", bg="white") myButton.pack() myLabel=Label(root, text="等待客户端连接...") myLabel.pack() root.mainloop()
关键改动说明
- 引入
threading模块,把原myClick里的Socket逻辑抽成receive_data函数,作为子线程的目标函数 myClick现在只负责启动子线程,操作瞬间完成,不会阻塞GUI主线程- 设置线程为
daemon=True,主窗口关闭时子线程会自动退出,避免残留进程 - 增加客户端断开时关闭Socket的逻辑,更规范
客户端代码无需修改,保持原样即可。启动服务器后点击按钮,GUI不会冻结,能实时显示客户端发送的计数器数值,客户端断开后线程自动结束。
内容的提问来源于stack exchange,提问作者Anthony J. B.
相关产品推荐
相关产品推荐

