Python Forum
RuntimeError: threads can only be started once
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
RuntimeError: threads can only be started once
#1
So I made this very simple tkinter python program

That where you enter start and stop time
and that works perfectly fine

If you reenter a new time
you will always get a


Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python311\Lib\threading.py", line 952, in start
    raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once
I'm trying to figure out how to catch this error in a try block
and have been unsuccessful here is my working program so far


"
import tkinter as tk
import schedule
import time
import threading

root = tk.Tk()
root.title("MyApp")
root.geometry("284x280+700+200")  # Size of the window

Start_Time1 = tk.StringVar()
Stop_Time1 = tk.StringVar()


def job():
    print("I'm working...")  # this is just for testing
    return schedule.CancelJob  # remove it from the scheduler


def time_up():
    schedule.clear()
    print('time has elapsed')  # this is just for testing
    time.sleep(2)
    # root.quit()  # this seems to work here, close the window and the program


def schedule_time():
    print("working...")  # this is just for testing
    schedule.every().day.at(Start_Time1.get()).do(job)  # or you can place your times in here
    schedule.every().day.at(Stop_Time1.get()).do(time_up)
    # print("schedule_time", Start_Time.get())  # this is just for testing

    while True:
        # Checks whether a scheduled task
        # is pending to run or not
        schedule.run_pending()
        if not schedule.jobs:  # this will stop after the last scheduled event
            break
        time.sleep(1)
        # root.destroy()  # if you want the main window to be terminated


# print("I'm done")  # this is just for testing


Message = tk.Label(root, text='Enter time as ( HH:MM )', font=('Arial', 12))
Message.place(x=50, y=10)

Start = tk.Label(root, text='Start_Time:', font=('Arial', 12))
Start.place(x=18, y=50)
text_entry = tk.Entry(root, width=8, textvariable=Start_Time1, font=('Arial bold', 12))
text_entry.place(x=116, y=50)  # x = left to right y = top to down

Stop = tk.Label(root, text='Stop_Time:', font=('Arial', 12))
Stop.place(x=18, y=90)
text_entry = tk.Entry(root, width=8, textvariable=Stop_Time1, font=('Arial bold', 12))
text_entry.place(x=116, y=90)

button1 = tk.Button(root, text="Start Time", font=('Arial', 12),
                    command=threading.Thread(target=schedule_time).start)
button1.place(x=50, y=125)

root.mainloop()
any help would be appreciated on trying to figure this out
Reply
#2
Please post the code that raises the error or post more of the error message to where it references the code in your post.

I don't think you want to catch this error. You should not be trying to re-start a thread. I think there is a logic error in your code.

Why is tkinter is mentioned in the traceback. tkinter code should only run in the main thread.
Reply
#3
(Nov-22-2024, 09:35 PM)deanhystad Wrote: Please post the code that raises the error or post more of the error message to where it references the code in your post.

I don't think you want to catch this error. You should not be trying to re-start a thread. I think there is a logic error in your code.

Why is tkinter is mentioned in the traceback. tkinter code should only run in the main thread.

I did post the code if you read up above you'll see if you try to reenter a time it will generate an error code

this is the error code it is a copy of the one up above

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\threading.py", line 952, in start
raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once
Reply
#4
The while loop for schedule needs to be in a separate thread. The code adding tasks to the schedule should be in the main thread. schedule_time() needs to be split into two functions.
Reply
#5
(Nov-23-2024, 11:23 AM)deanhystad Wrote: The while loop for schedule needs to be in a separate thread. The code adding tasks to the schedule should be in the main thread. schedule_time() needs to be split into two functions.

Okay I apologize I guess I misunderstood I will put it all together and then we edit my post
Reply
#6
(Nov-23-2024, 11:23 AM)deanhystad Wrote: The while loop for schedule needs to be in a separate thread. The code adding tasks to the schedule should be in the main thread. schedule_time() needs to be split into two functions.

Okay I will look into that
but that doesn't really answer my question, how do I catch the error in a try loop
Reply
#7
If the code is written correctly the error will not occur
Reply
#8
(Nov-24-2024, 04:16 AM)deanhystad Wrote: If the code is written correctly the error will not occur

Well forgive me for saying this but can you please explain that
if my code is not correct it will generate the error but if you try to reenter a number it will do so
so how do I fix it
Reply
#9
Like this:
import tkinter as tk
import schedule
import time
import threading


def job():
    print("I'm working...")  # this is just for testing
    return schedule.CancelJob  # remove it from the scheduler


def time_up():
    schedule.clear()
    print('time has elapsed')  # this is just for testing


def schedule_time():
    """Add a job to the scheduler"""
    schedule.every().day.at(start_time.get()).do(job)
    schedule.every().day.at(stop_time.get()).do(time_up)


def schedule_thread():
    """Run pending jobs."""
    while running:
        # For debugging, print list of pending jobs.
        time.sleep(10)
        print(schedule.get_jobs())
        schedule.run_pending()


def end_program():
    """End schedule thread so program can exit."""
    global running
    running = False
    root.destroy()


root = tk.Tk()
root.protocol("WM_DELETE_WINDOW", end_program)
start_time = tk.StringVar()
tk.Label(root, text='Start (HH:MM[:SS]):').grid(row=0, column=0, padx=10, pady=10)
tk.Entry(root, width=8, textvariable=start_time).grid(row=0, column=1, padx=10)
stop_time = tk.StringVar()
tk.Label(root, text='Stop (HH:MM[:SS]):').grid(row=1, column=0, padx=10, pady=10)
tk.Entry(root, width=8, textvariable=stop_time).grid(row=1, column=1, padx=10)
tk.Button(
    root, text="Run", command=schedule_time
).grid(row=2, column=0, columnspan=2, padx=10, pady=10, sticky="news")

running = True
scheduler_thread = threading.Thread(target=schedule_thread)
scheduler_thread.start()

root.mainloop()
At the start of the program create a thread that runs the schedule. This thread runs for the entirety of the program. The run button adds a new job to the schedule. Scheduling a job does not start a new thread. When shutting down the program you need to stop the scheduler thread.
Reply
#10
(Nov-24-2024, 12:45 PM)deanhystad Wrote: Like this:
import tkinter as tk
import schedule
import time
import threading


def job():
    print("I'm working...")  # this is just for testing
    return schedule.CancelJob  # remove it from the scheduler


def time_up():
    schedule.clear()
    print('time has elapsed')  # this is just for testing


def schedule_time():
    """Add a job to the scheduler"""
    schedule.every().day.at(start_time.get()).do(job)
    schedule.every().day.at(stop_time.get()).do(time_up)


def schedule_thread():
    """Run pending jobs."""
    while running:
        # For debugging, print list of pending jobs.
        time.sleep(10)
        print(schedule.get_jobs())
        schedule.run_pending()


def end_program():
    """End schedule thread so program can exit."""
    global running
    running = False
    root.destroy()


root = tk.Tk()
root.protocol("WM_DELETE_WINDOW", end_program)
start_time = tk.StringVar()
tk.Label(root, text='Start (HH:MM[:SS]):').grid(row=0, column=0, padx=10, pady=10)
tk.Entry(root, width=8, textvariable=start_time).grid(row=0, column=1, padx=10)
stop_time = tk.StringVar()
tk.Label(root, text='Stop (HH:MM[:SS]):').grid(row=1, column=0, padx=10, pady=10)
tk.Entry(root, width=8, textvariable=stop_time).grid(row=1, column=1, padx=10)
tk.Button(
    root, text="Run", command=schedule_time
).grid(row=2, column=0, columnspan=2, padx=10, pady=10, sticky="news")

running = True
scheduler_thread = threading.Thread(target=schedule_thread)
scheduler_thread.start()

root.mainloop()
At the start of the program create a thread that runs the schedule. This thread runs for the entirety of the program. The run button adds a new job to the schedule. Scheduling a job does not start a new thread. When shutting down the program you need to stop the scheduler thread.



Thank you very much for your help it does work the way it's supposed to I appreciate it
I will look it over and compare with what I have and see where I made the error
it's a great learning tool thank you very much
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Help To Get Started HansieB 5 956 Nov-29-2024, 03:06 PM
Last Post: HansieB
  Cannot get started standenman 4 2,279 Feb-22-2023, 05:25 PM
Last Post: standenman
  help RuntimeError: no running event loop marpaslight 5 7,975 Oct-18-2022, 10:04 PM
Last Post: marpaslight
  bleak library RuntimeError: This event loop is already running alice93 3 6,518 Sep-30-2021, 08:06 AM
Last Post: alice93
  RuntimeError: generator raised StopIteration quest 1 7,179 Mar-28-2021, 08:11 PM
Last Post: quest
  RuntimeError: This event loop is already running newbie2019 2 7,941 Sep-30-2020, 06:59 PM
Last Post: forest44
  Can't even get started dr6 1 2,130 Aug-18-2020, 04:38 PM
Last Post: Larz60+
  RuntimeError: Optimal parameters not found: Number of calls to function has reached m bntayfur 0 7,513 Aug-05-2020, 04:41 PM
Last Post: bntayfur
  RuntimeError: can't open file Hadad 2 6,533 Aug-27-2019, 04:23 PM
Last Post: Hadad
  RuntimeError: dictionary changed size during iteration Shreeniket987 3 6,099 Jun-01-2019, 01:22 PM
Last Post: buran

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020