Home > Net >  tkinter - Why is global variable not changed after function?
tkinter - Why is global variable not changed after function?

Time:01-31

window = Tk() #create app window



#custom message box function 
def answerMessagebox(returnValue, toplevel, functionName=""):
    global answer
    answer = returnValue

    print("The answer variable is (inside answerMessagebox function): ", answer)

    if functionName: #if there is a command do this
        functionName()

    toplevel.destroy() #close messagebox

def messageboxYesNo(title, text, functionName=""):

    toplevel = Toplevel(window)
 
    toplevel.title(title)
    
    l1=Label(toplevel, image=iconQuestion)
    l1.grid(row=0, column=0, pady=(7, 0), padx=(10, 30), sticky="e")

    l2=Label(toplevel,text=text)
    l2.grid(row=0, column=1, columnspan=3, pady=(7, 10), sticky="w")
 
    b1=Button(toplevel,text="Yes",command=lambda: answerMessagebox(True, toplevel, functionName=functionName),width = 10)
    b1.grid(row=1, column=1, padx=(2, 35), sticky="e")

    b2=Button(toplevel,text="No",command= lambda: answerMessagebox(False, toplevel), width = 10)
    b2.grid(row=1, column=2, padx=(2, 35), sticky="e")



def close_window():
    driver.quit() 
    window.destroy()
    exit() 

exitButton = Button(window, text="Exit", command=lambda: messageboxYesNo("QUIT", "Are you sure you want to Quit?", functionName=close_window), font=breadtextFont, bg=button_color, fg=button_text_color) #add a exit button
exitButton.pack(side="top", anchor=NE, padx=15, pady=10)

window.mainloop()

The print statement inside answerMessagebox prints out correctly False if I press No-button and True if I press Yes-button. I want to use that answer inside another function and do logic based on the answer.

def foo():
    global answer
    answer = ""
    messageboxYesNo("Submit report", "Are you sure you want to submit?") #expect global variable to change to True if press Yes-button. But it actually prints out nothing. 

    if answer:
       #do something 

Inside the foo()function the global variable answerdoes not change after I run the messageboxYesNo function and therefore the if answer: statements is not running.

Why is the global variable not changing? I guess it is because foo() continues and is not waiting for messageboxYesNo function to finish. How can I solve this issue?

I use a global variable because the command= in tkinter cannot return anything from a function.

CodePudding user response:

Your code does not show when foo() is being executed, however at the beginning you are already overriding the value of answer with an empty string, which later evaluates to false:

def foo():
    global answer
    answer = "" # Remove this line

There are many issues with this usage of global variables, and an OOP refactor would be the best approach to address it. However, a quick solution for this specific problem would be passing the result from answerMessagebox to the callback:

def answerMessagebox(returnValue, toplevel, functionName=""):
    answer = returnValue
    print("The answer variable is (inside answerMessagebox function): ", answer)

    if functionName:
        functionName(answer)
    # ...

def foo(answer):
    # ...

CodePudding user response:

The last print statement is executed soon after you press the Exit button. It simply creates the UI for the labels and the Yes/No buttons, prints the last statement and exists the function.

When you press the Yes/No buttons, it executes the answerMessagebox function. If you want something to execute after the changes to answer have been made, either add it to the end of the answerMessagebox function or (maybe in the case that it doesn't make sense to have it on the same function) execute a separate function at the end of the function:

def answerMessagebox(returnValue, toplevel, functionName=""):
    answer = returnValue
    
    # The logic you've written already
    
    toplevel.destroy() #close messagebox
    
    everythingAfterYesNoPress(answer)


def everythingAfterYesNoPress(answer = ""):
    print("This is answer variable after messageboxYesNo function", answer)

Edit: I think what you're looking for is wait_window.

Initialize toplevel inside the foo function before the messageboxYesNo function and pass it as a parameter to the function instead of defining it inside (of course, you'd have to change the messageboxYesNo function a bit). Then add the wait_window line after executing the function:

toplevel = Toplevel(window)
messageboxYesNo(toplevel, "Submit report", "Are you sure you want to submit?")
window.wait_window(toplevel)
  •  Tags:  
  • Related