wojtas
wojtas

Reputation: 3

Tkinter Button Function Control by MessageBox

The code below shows part of my program and the issue im facing.

def checkAnswer():
mainAnswer = answer01.get()
if len(mainAnswer) == 0:
    messagebox.showwarning(message='Please answer the question!')
    return
if int(mainAnswer) != answer:
    messagebox.showwarning(message='Incorrect! The correct answer is: ' + str(answer))
else:
    nxtquest.config(state=NORMAL)
    messagebox.showinfo(message='Correct! :)')question01 = Label(easy)
question01.grid(row=2, column=0)
answer01 = Entry(easy)
answer01.grid(row=3, column=2)
answer01.bind('<Return>', func=lambda e:checkAnswer())
start = Button(easy, text = "Start!", command=ask, bg='green', fg='white')
start.grid(row=3, column=3) 
nxtquest = Button(easy, text='Next Question', command=ask)
nxtquest.grid(row=5, column=2)
checkbut = Button(easy, text='Check', command=checkAnswer)
checkbut.grid(row=4, column=2)
#check button and answer01 enabled after start pressed
launch = 1 
if launch == 1:
    answer01.config(state=DISABLED)
    checkbut.config(state=DISABLED)
    nxtquest.config(state=DISABLED)

The issue which im struggling here is that whenever i run the program everything is okay. When the window is displayed checkbut, nxtquest and label answer01 are greyed out (disabled). The start button enables only checkbut and answer01 and then is destroyed. (So far so good) So nxtquest will enable once the input is correct as seen in the else: nxtquest.config(state=NORMAL) But when I reach another question the nxtquest button is already enabled, this is the problem!

How could I make it so the button will enable itself only after the warning message box is displayed?

Could I ask for some help with this and possibly suggestions if you see any rookie mistakes ?

Upvotes: 0

Views: 1048

Answers (1)

Ethan Field
Ethan Field

Reputation: 4730

Whilst I don't know of any way you could do this with a messagebox widget (although I'm sure there's an event you could use as the trigger) you can most certainly do this by substituting the messagebox with a Toplevel widget and using .protocol("WM_DELETE_WINDOW", callback()) on the widget.

This would mean that whenever the Toplevel widget was "closed" we would actually be overwriting the action taken when the event was raised and would manually handle the closing of the widget as well as whatever else we wanted it to do.

This would look something like the below:

from tkinter import *

root = Tk()

button = Button(root, text="Ok", state="disabled")
button.pack()

top = Toplevel(root)

def close():
    top.destroy()
    button.configure(state="active")

top.protocol("WM_DELETE_WINDOW", close)

root.mainloop()

If you close the Toplevel widget you will see that the button is now active instead. This would equally work if we added a Button to the Toplevel widget which called the function close().

Upvotes: 1

Related Questions