Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Thread can only be started once error in Tkinter

I am creating a client web socket that connects to a server.
And I am starting the connection using a Tkinter gui button. To prevent gui from getting stuck I am using threading. My client disconnects from the server after some time. So when I try to connect again using the button it shows an error that a Thread can only be started once.

My code for Button and client method:

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)

Error

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I was expecting that client connects again without errors

>Solution :

This expression creates a new Thread object, and then it creates and returns a new functional object whose __call__ method starts the new thread:

threading.Thread(target=on_click).start

You can call the functional object any number of times, but every time you call it, it tries to start the same thread. That’s not allowed. It’s just like the error message says. A Thread object may only be started one time.

When you said, command=threading.Thread(target=on_click).start, you’re giving the Button a command that tries to start the same thread again and again. You need to provide a command that starts a new thread every time.

The most obvious way (in my personal opinion) is to declare another function:

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
             )

But, you can also do what @TheLizard said in a comment. lambda:threading.Thread(target=on_click).start() also is an expression that returns a new functional object. But, the difference is, its __call__ method creates a new Thread every time—creates and then starts it. Specifically, it’s __call__ method does this:

threading.Thread(target=on_click).start()
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading