You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 05:15:37