1

I'm currently building a small Tkinter app that executes a pre-written function based on the numbers a user inputs. When I run my code, everything works fine until I get to the function named count_func().

The goal of this Tkinter app is to execute main_func() according to a user-set speed rate and then automatically stop itself after reaching the user-set execution count.

home_win = Tk()
home_win.title("My App's Name")
home_win.configure(bg='gray')

    e1 = Entry(home_win, width=6, justify=CENTER, bd=1, fg='green', font=('bold',11), relief='groove')
    e1.grid(column=1, row=2, sticky=W, pady=0, padx=0)

    e2 = Entry(home_win, width=6, justify=CENTER, bd=1, fg='green', font=('bold',11), relief='groove')
    e2.grid(column=1, row=3, sticky=W, pady=0, padx=0)

    e3 = Entry(home_win, width=6, justify=CENTER, bd=1, fg='green', font=('bold',11), relief='groove')
    e3.grid(column=1, row=4, sticky=W, pady=0, padx=0)

    def main_func():
        # THIS PERFORMS MY MAIN TASK

    def start_delay():
        time.sleep(int(e1.get())) # USER INPUTS THE DESIRED START DELAY TIME

    def speed_func():
        schedule.every(float(e2.get())).seconds.do(main_func) # USER INPUTS HOW FAST `main_func()` EXECUTES
        while True:
            schedule.run_pending()

    def count_func(): # USER INPUTS HOW MANY TIMES `speed_func()` EXECUTES BEFORE STOPPING AUTOMATICALLY
        for count in range(int(e3.get())):
            if count <= int(e3.get())):
                speed_func()
            else:
                break

    button1 = Button(home_win, text="RUN", command=lambda:[start_delay(), count_func()])
    button1.grid(column=0, row=10, sticky=E, pady(32,32), padx=(0,10))

home_win.mainloop()

I've tried several different types of loops and makeshift incrementing functions, but ended up with error messages outright. I've also tried to close out the schedule.run_pending() block a couple different ways, e.g., pass or return statements, but ended up breaking the entire speed_func() function as a result.

Any insight from the community is much appreciated. Thanks for reading!

psps
  • 13
  • 4

1 Answers1

0

You have an infinite while loop inside of a for loop, and also each time speed_func() is called, another instance of main_func() is scheduled to run every few seconds. Instead of trying to stop schedule from within speed_func() lets create a separate function to cancel the job, also lets try to run schedule.run_pending() in a separate thread.

import threading
import schedule
import time
from tkinter import *

home_win = Tk()
home_win.title("My App's Name")
home_win.configure(bg='gray')

e1 = Entry(home_win, width=6, justify=CENTER, bd=1, fg='green', font=('bold',11), relief='groove')
e1.grid(column=1, row=2, sticky=W, pady=0, padx=0)

e2 = Entry(home_win, width=6, justify=CENTER, bd=1, fg='green', font=('bold',11), relief='groove')
e2.grid(column=1, row=3, sticky=W, pady=0, padx=0)

e3 = Entry(home_win, width=6, justify=CENTER, bd=1, fg='green', font=('bold',11), relief='groove')
e3.grid(column=1, row=4, sticky=W, pady=0, padx=0)

def main_func():
    # THIS PERFORMS MY MAIN TASK
    print("Main task executed")

def start_delay():
    time.sleep(int(e1.get())) # USER INPUTS THE DESIRED START DELAY TIME

def speed_func():
    job = schedule.every(float(e2.get())).seconds.do(main_func) # USER INPUTS HOW FAST `main_func()` EXECUTES
    return job

def count_func(job): # USER INPUTS HOW MANY TIMES `speed_func()` EXECUTES BEFORE STOPPING AUTOMATICALLY
    for count in range(int(e3.get())):
        if count <= int(e3.get())):
            time.sleep(float(e2.get())) # simulate the execution of main_func
        else:
            schedule.cancel_job(job)
            break

def run_schedule():
    while True:
        schedule.run_pending()
        time.sleep(1)

button1 = Button(home_win, text="RUN", command=lambda:[start_delay(), count_func(speed_func())])
button1.grid(column=0, row=10, sticky=E)

t = threading.Thread(target=run_schedule)
t.start()

home_win.mainloop()
Saxtheowl
  • 4,136
  • 5
  • 23
  • 32