Python Tkinter While Thread
Question: Well i am a bit of newb at python, and i am getting hard to make a thread in
Tkinter , as you all know using while in Tkinter makes it Not Responding and
the script still running.

    
    
      def scheduler():
        def wait():
            schedule.run_pending()
            time.sleep(1)
            return
        Hours = ScheduleTest()
        if len(Hours) == 0:
            print("You need to write Hours, Example: 13:30,20:07")
        if len(Hours) > 0:
            print("Scheduled: ", str(Hours))
            if len(Hours) == 1:
                schedule.every().day.at(Hours[0]).do(Jumper)
                print("Will jump 1 time")
            elif len(Hours) == 2:
                schedule.every().day.at(Hours[0]).do(Jumper)
                schedule.every().day.at(Hours[1]).do(Jumper)
                print("Will jump 2 times")
            elif len(Hours) == 3:
                schedule.every().day.at(Hours[0]).do(Jumper)
                schedule.every().day.at(Hours[1]).do(Jumper)
                schedule.every().day.at(Hours[2]).do(Jumper)
                print("Will jump 3 times")
            while True:
                t = threading.Thread(target=wait)
                t.start()
        return
    scheduler()
    

i have tried to do something like this but it still makes tkinter not
responding Thanks in advance.


Answer: ### When to use the after method; faking while without threading

As mentioned in a comment, In far most cases, you do not need threading to run
a "fake" while loop. You can use the `after()` method to schedule your
actions, using `tkinter`'s `mainloop` as a "coat rack" to schedule things,
pretty much exactly like you would in a while loop.

This works in all situations where you can simply throw out commands with e.g.
`subprocess.Popen()`, update widgets, show messages etc.

It does _not_ work when the scheduled process takes a lot of time, running
_inside_ the mainloop. Therefore `time.sleep()` is a bummer; it will simply
hold the `mainloop`.

### How it works

Within that limitation however, you can run complicated tasks, schedule
actions even set `break` (-equivalent) conditions.

Simply create a function, initiate it with `window.after(0, <function>)`.
Inside the function, (re-) schedule the function with
`window.after(<time_in_milliseconds>, <function>)`.

To apply a break- like condition, simply rout the process (inside the
function) not to be scheduled again.

### An example

This is best illustrated with a simplified example:

[![enter image description
here](http://i.stack.imgur.com/pj8bS.png)](http://i.stack.imgur.com/pj8bS.png)

[![enter image description
here](http://i.stack.imgur.com/5s8Ux.png)](http://i.stack.imgur.com/5s8Ux.png)

[![enter image description
here](http://i.stack.imgur.com/kO16M.png)](http://i.stack.imgur.com/kO16M.png)

    
    
    from tkinter import *
    import time
    
    class TestWhile:
    
        def __init__(self):
    
            self.window = Tk()
            shape = Canvas(width=200, height=0).grid(column=0, row=0)
            self.showtext = Label(text="Wait and see...")
            self.showtext.grid(column=0, row=1)
            fakebutton = Button(
                text="Useless button"
                )
            fakebutton.grid(column=0, row=2)
    
            # initiate fake while
            self.window.after(0, self.fakewhile)
            self.cycles = 0
    
            self.window.minsize(width=200, height=50)
            self.window.title("Test 123(4)")
            self.window.mainloop()
    
        def fakewhile(self):
            # You can schedule anything in here
            if self.cycles == 5:
                self.showtext.configure(text="Five seconds passed")
            elif self.cycles == 10:
                self.showtext.configure(text="Ten seconds passed...")
            elif self.cycles == 15:
                self.showtext.configure(text="I quit...")
            """
            If the fake while loop should only run a limited number of times,
            add a counter
            """
            self.cycles = self.cycles+1
            """
            Since we do not use while, break will not work, but simply
            "routing" the loop to not being scheduled is equivalent to "break":
            """
            if self.cycles <= 15:
                self.window.after(1000, self.fakewhile)
            else:
                # start over again
                self.cycles = 0
                self.window.after(1000, self.fakewhile)
                # or: fakebreak, in that case, uncomment below and comment out the
                # two lines above
                # pass
    
    TestWhile()
    

In the example above, we run a scheduled process for fifteen seconds. While
the loop runs, several simple tasks are performed, in time, by the function
`fakewhile()`.

After these fivteen seconds, we can start over again or "break". Just
uncomment the indicated section to see...

