Starting n threads with same function at diffrent times

Question:

I’m currently working with Tkinter to create a GUI for my Script. Among other things there is a function which writes and save some Data in some Files. To visualize the progress for the User i got an label which shows the progress. When i press the button to execute the function

button_download_data = tk.Button(text="Get Data",command=gatherData)

the window freezes and beside the counter for the progress increasaes it isnt shown due to the window is frozen. My solution was to start the function in a new thread using the threading modul.

button_download_data = tk.Button(text="Get Data",command=threading.Thread(target=gatherData).start)

Now the progress is showed but i cant press the button again because i get an error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:WPy64-31050python-3.10.5.amd64libtkinter__init__.py", line 1921, in __call__
    return self.func(*args)
  File "C:WPy64-31050python-3.10.5.amd64libthreading.py", line 930, in start
    raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once

I tried to "kill" the thread when the function is done with raise Exception() and sys.Exit() but it doesn’t work at all.
I figuerd out that i can outsource the thread start out of the tkinter button line with:

def gatherDate():
    do something

def threadStart():
    threading.Thread(target=gatherData).start

button_download_data = tk.Button(text="Get Data",command=threadStart)

and i think it might help to start a new thread on button press and not the same again but i cant imagine how.

Asked By: Elperdano

||

Answers:

You should be able to handle this by creating a separate function to spawn new worker threads as needed – here’s a very basic example

import tkinter as tk
from threading import Thread
from time import sleep  # for example - simulate a long-running process


def get_data():
    print('foo')  # do whatever you need to do here
    sleep(2.0)  # simulate the thread 'working' on something...for example


def spawn_thread():
    t = Thread(target=get_data, daemon=True)
    t.start()


root = tk.Tk()
button_download_data = tk.Button(root, text='Get Data', command=spawn_thread)
button_download_data.pack()


if __name__ == '__main__':
    root.mainloop()

You could simplify spawn_thread a little by skipping the variable assignment t=... and doing Thread(target=get_data, daemon=True).start() instead (as long as you don’t need access to the Thread object t for anything else)

Answered By: JRiggles
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.