我正在创建一个连接到服务器的客户端 Web 套接字。 我正在使用 Tkinter gui 按钮启动连接。为了防止 gui 被卡住,我使用了线程。一段时间后,我的客户端与服务器断开连接。因此,当我尝试使用按钮再次连接时,它会显示一个错误,即线程只能启动一次。
我的按钮和客户端方法的代码:
async def start_client(url, duration):
async with websockets.connect(url) as ws:
start_time = time.time()
while time.time() - start_time < duration:
message = await ws.recv()
msg = json.loads(message)
print(msg)
if 'timestamp android.sensor.accelerometer' in msg:
write_acc(msg)
else:
write_gyro(msg)
def on_click():
initial_setup_files()
asyncio.run(start_client(url, 4))
final_csv_file_creator()
print("Disconnected from the server")
btn = Button(window,
text="Start Server ",
fg="black",
bg="cyan",
font=("Times New Roman", 30, 'bold'),
command=threading.Thread(target=on_click).start
)
btn.pack(padx=20,
pady=20)
我期待客户端再次连接而不会出现错误
这是一个创建新
Thread
对象的表达式,表达式的值是 Thread
对象本身。
threading.Thread(target=on_click)
this表达式的值是一个函数对象。具体来说,它创建一个新的 Thread
,然后返回一个函数对象,其
__call__
方法启动线程:
threading.Thread(target=on_click).start
您可以多次调用函数对象,但每次调用它时,它都会尝试启动相同的线程。这是不允许的。就像错误消息所说的那样。一个 Thread
对象只能启动一次。当您说,
command= threading.Thread(target=on_click).start
时,您正在给
Button
一个尝试一次又一次启动同一个线程的
command
。您需要提供一个每次启动一个新线程的
command
。最简单的方法,可能是声明另一个函数:
def handle_button_press():
threading.Thread(target=on_click).start
btn = Button(window,
text="Start Server ",
fg="black",
bg="cyan",
font=("Times New Roman", 30, 'bold'),
command=handle_button_press
)