0

I have a while loop that I want to run while the Tkinter window is open but the Tkinter window doesn't even open when the while loop is running.

This is a problem since my while loop is an infinite loop.

I basically want to create a programme that provides the users with new choices after a previous choice is selected by updating the buttons through a while loop, but whenever I use a while loop Tkinter doesn't open the window until I end the loop.

root = Tk()
i=0
while i==0:
    def choice1():
        list1[a1].implement()
        list1.remove(list1[a1])
    def choice2():
        list2[a2].implement()
        list2.remove(list2[a2])

button1 = tk.Button(root, text=list1.headline, command=choice1)
button2 = tk.Button(root, text=list2.headline, command =choice2)
root.mainloop()

Also, an error shows up because tkinter keeps executing this loop until there are no items in list1 or list2 left.

What I want to know is if there is a way to run Tkinter window while the while loop is going on

(a1 and a2 are randomly generated numbers.)

martineau
  • 119,623
  • 25
  • 170
  • 301
ADUCJ
  • 123
  • 2
  • 13
  • 2
    Tkinter apps won't function if you interfere or prevent the `mainloop()` from running. See @Bryan Oakley's answer to [Tkinter — executing functions over time](https://stackoverflow.com/questions/9342757/tkinter-executing-functions-over-time). Also note that your infinite `while` loop is doing nothing by **defining** the two functions over-and-over — they are never called in the loop. – martineau Apr 03 '20 at 17:21
  • 2
    Put `root.mainloop()` *in* the `while` loop. – Captain Jack Sparrow Apr 03 '20 at 17:27
  • The `mainloop()` is the main reason for the window to be displayed continuously. When the `while loop` is running the `mainloop()` does not get executed until the `while loop` ends because the code including the `mainloop()` waits till its turn to be executed. As the code on the top gets executed first. – DaniyalAhmadSE Apr 03 '20 at 19:00
  • @Noah: Putting the call to `root.mainloop()` in the `while` loop will prevent it from iterating because the former function won't return until the application window is closed — so it **won't** fix anything. – martineau Apr 05 '20 at 20:53
  • @martineau Oh ok lol. Shows what I know about Tk. – Captain Jack Sparrow Apr 05 '20 at 23:13

3 Answers3

1

The mainloop() is the main reason for the window to be displayed continuously. When the while loop is running, the mainloop() does not get executed until the while loop ends. And because in your case the while loop never ends, the code including the mainloop() keeps waiting for its turn to be executed.

To overcome this issue you will have to put all the widgets you want to be displayed in the window along with the mainloop() inside the while loop

Like this:

import tkinter as tk

root = tk.Tk()

i = 0

while i == 0:

    def choice1():
        list1[a1].implement()
        list1.remove(list1[a1])

    def choice2():
        list2[a2].implement()
        list2.remove(list2[a2])


    button1 = tk.Button(root, text=list1.headline, command=choice1)
    button2 = tk.Button(root, text=list2.headline, command=choice2)

    root.mainloop()
DaniyalAhmadSE
  • 807
  • 11
  • 20
0

You should probably put root.mainloop in the loop, otherwise it will never execute. If mainloop() doesn't execute, the window won't stay open.

And also: you need to call the functions, defining them isn't enough. So instead of in the loop only having the def choice1() and def choice2() you need to also have choice1() and choice2() in the loop, otherwise it won't execute those commands.

And one more thing: you need to pack() the buttons, so add the lines button1.pack() and button2.pack(). The buttons also need to be before the loop, which means your def choice1() and def choice2() need to be before the loop also. (The buttons will never show up otherwise)

TheTechRobo the Nerd
  • 1,249
  • 15
  • 28
  • Yeah, i know about the packing bit I just didnt display it here as I wanted to just show the main problem that I was having, also the functions are being called in the button commands. – ADUCJ Apr 04 '20 at 03:33
  • So essentially @ADUCJ you need to put the widgets and mainloop inside the while loop. You also need to invoke choice1() and choice2() inside the while loop instead of just defining them. Make sure to mark the solution that works as Solved with the checkmark button on the left. – TheTechRobo the Nerd Apr 04 '20 at 20:59
  • Rereading your comment. Ok, then you don't need the while loop as the commands are invoked with the buttons. You can just put the def statements outside of the while loop, you don't need the loop. It isn't useful. – TheTechRobo the Nerd Apr 04 '20 at 21:03
  • 1
    "You should probably put root.mainloop in the loop". no this is a while loop so putting a loop in a loop probably isnt a good idea. in contrast one iteration of root.mainloop is root.update_idletasks;root.update(). (semicolon meaning newline) – somebody Oct 02 '22 at 15:53
  • Right, yes, sorry. I wrote this answer a long time ago, before I knew much about programming. – TheTechRobo the Nerd Oct 02 '22 at 16:00
0

tkinter runs in its own loop, each button/widget/element can be tied to more advanced functions. Judging by your script, you have your functions built into your loop, if you place them outside of the loop, you can then enhance their usability.

Your code:

root = Tk()
i=0
while i==0:
    def choice1():
        list1[a1].implement()
        list1.remove(list1[a1])
    def choice2():
        list2[a2].implement()
        list2.remove(list2[a2])

button1 = tk.Button(root, text=list1.headline, command=choice1)
button2 = tk.Button(root, text=list2.headline, command =choice2)
root.mainloop()

Suggested code:

root = Tk()

i=0

def choice1():
    list1[a1].implement()
    list1.remove(list1[a1])

def choice2():
    list2[a2].implement()
    list2.remove(list2[a2])

while i==0:

 # put here, what this extra loop will do.#

button1 = tk.Button(root, text=list1.headline, command=choice1)
button2 = tk.Button(root, text=list2.headline, command =choice2)
root.mainloop()

danronmoon
  • 3,814
  • 5
  • 34
  • 56