I have a game, When a button is created, I need my program to just show this screen untill they press 'Next Level' all of this code is in a while loop so in a large while loop controlling the game.
......
if game.playerDistance >= game.lowerBound() and game.playerDistance <= game.upperBound():
game.level += 1
showLevelResults(game)
#NextLevelButton
btnNextLevel = Button(root,
#Random Config
command = nextLevel,
)
btnNextLevel.place(x=1003, y=492, anchor=NW, width=247, height=78)
updateMainScreen()
while nextLev == False:
#What Do I put in here to force a wait
else:
......
nextLev = False
def nextLevel():
nextLev = True
...
Currently this keeps it in the while loop and when the button is pressed nothing changes i have used time.sleep(1) to keep it waiting and also had it printing waiting for btn press, however this spams the console and when the button is pressed still doesnt change the screen.
def showGameSurvival():
game = gamemode_normal()
while game.health != 0:
game.next = False
clearScreen()
changeBackground("Survival")
#Placing Labels on the screen for game.....
#... Health
root.update()
lblCountDownLeft = Label(root, bg="White", fg="Green", font=XXLARGE_BUTTON_FONT)
lblCountDownLeft.place(x=169, y=350, anchor=CENTER)
lblCountDownRight = Label(root, bg="White", fg="Green", font=XXLARGE_BUTTON_FONT)
lblCountDownRight.place(x=1111, y=350, anchor=CENTER)
#CountDown
count = 7
while count > 0:
lblCountDownLeft['text'] = count
lblCountDownRight['text'] = count
root.update()
count -= 1
time.sleep(1)
lblCountDownLeft.destroy()
lblCountDownRight.destroy()
root.update()
#Num on left x=169, right, x=1111 y=360
game.measureDistance()
if game.playerDistance >= game.lowerBound() and game.playerDistance <= game.upperBound():
game.level += 1
clearScreen()
changeBackground("Survival")
graphicalDisplay(game)
#NextLevelButton
btnNextLevel = Button(root,
bg= lbBlue,
fg="white",
text="Level" + str(game.level),
font=SMALL_BUTTON_FONT,
activebackground="white",
activeforeground= lbBlue,
command= lambda: nextLevel(game),
bd=0)
btnNextLevel.place(x=1003, y=492, anchor=NW, width=247, height=78)
root.update()
while game.next == False:
print(game.next)
else:
game.health -= 1
if game.allowance > 4:
game.allowance = int(game.allowance*0.9)
#when game is over delete the shit
if game.health == 0:
del game
The next button now calls this function: def nextLevel(game):
game.next = True
The simplest way to get tkinter to wait for some event is to call one of the "wait" functions, such as wait_variable, wait_window, or wait_visibility.
In your case you want to wait for a button click, so you can use wait_variable
and then have the button set the variable. When you click the button the variable will be set, and when the variable is set the call to wait_variable
will return.
For example:
import tkinter as tk
root = tk.Tk()
...
var = tk.IntVar()
button = tk.Button(root, text="Click Me", command=lambda: var.set(1))
button.place(relx=.5, rely=.5, anchor="c")
print("waiting...")
button.wait_variable(var)
print("done waiting.")
Note: you don't have to use IntVar
-- any of the special Tkinter variables will do. Also, it doesn't matter what you set it to, the method will wait until it changes.
Just wanted to add a comment, but don't have enough reputation. I couldn't get the wait_variable(var) to work for me on the button. I had to use it on my frame. I'm guessing this is a change between Python 2 and 3.
Here is the error I got:
Traceback (most recent call last):
File "AutoPlotHydroData2.py", line 434, in btnOK.wait_variable(okVar) AttributeError: 'NoneType' object has no attribute 'wait_variable'
My working code reads:
# Launch frame to collect needed input values
myFrame = tk.Tk()
myFrame.configure(background='lightblue')
# Add some widgets
# OK Button
okVar = tk.IntVar()
btnOK = tk.Button(myFrame, text="Submit", pady=5, font=("Arial Bold", 10),
bg='lightgray', command=lambda: okVar.set(1)).grid(row=14, column=0)
# Show frame
myFrame.tkraise()
# Wait for OK button to be pressed
#btnOK.wait_variable(okVar) - this didn't work
myFrame.wait_variable(okVar)
# Close frame
myFrame.destroy()
I have this code in a loop to process multiple files. Hope this helps someone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With