tkinter - 为什么全局变量在函数后没有改变?

tkinter - Why is global variable not changed after function?

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()

answerMessagebox 中的 print 语句正确打印 False 如果我按下否按钮,如果我按下是按钮 True。我想在另一个函数中使用那个答案,并根据答案做逻辑。

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 

foo() 函数内部,全局变量 answer 在我 运行 messageboxYesNo 函数之后没有改变,因此 if answer: 语句不是 运行宁.

为什么全局变量没有变化?我猜这是因为 foo() 继续并且没有等待 messageboxYesNo 函数完成。我该如何解决这个问题?

我使用全局变量,因为 tkinter 中的 command= 不能 return 函数中的任何内容。

最后一条打印语句在您按下Exit 按钮后立即执行。它只是为标签和 Yes/No 按钮创建 UI,打印最后一条语句并存在函数。

当您按下 Yes/No 按钮时,它会执行 answerMessagebox 功能。如果您想在对 answer 进行更改后执行某些操作,请将其添加到 answerMessagebox 函数的末尾,或者(也许在启用它没有意义的情况下)相同的函数)在函数的末尾执行一个单独的函数:

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)

编辑: 我想你要找的是 wait_window.

foo函数之前初始化toplevel函数,然后在messageboxYesNo函数之前将其作为参数传递给函数,而不是在函数内部定义它(当然,你必须稍微更改 messageboxYesNo 函数)。然后在执行函数后添加wait_window行:

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

您的代码在执行 foo() 时不显示,但是在开始时您已经用空字符串覆盖了 answer 的值,该字符串后来计算为 false:

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

全局变量的这种用法存在很多问题,OOP 重构将是解决该问题的最佳方法。但是,针对此特定问题的快速解决方案是将 answerMessagebox 的结果传递给回调:

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

    if functionName:
        functionName(answer)
    # ...

def foo(answer):
    # ...