Tkinter游戏菜单脚本问题:按下Esc键无法关闭窗口
问题原因
你的代码中root2是Game1函数内的局部变量,而close函数定义在全局作用域,无法访问这个局部变量。当按下Esc键触发close函数时,执行root2.destroy()会因为找不到root2对象而静默失败(Tkinter的事件绑定默认不会抛出未定义变量的报错),所以窗口没有任何反应。
解决方案
下面提供三种可行的解决方式,按需选择:
方案1:使用全局变量声明
将root2声明为全局变量,让close函数可以访问到它:
from tkinter import Tk, Canvas, Button import pyautogui as p root = Tk() root2 = None # 提前初始化全局变量 c = Canvas(root, width=400, height=400) def close(event): global root2 if root2: root2.destroy() def Game1(): global root2 # 声明使用全局作用域的root2 root.destroy() root2 = Tk() sx, sy = p.size() root2.attributes('-fullscreen', True) c2 = Canvas(root2, width=sx, height=sy, bg='green') c2.pack() root2.bind("<Escape>", close) root2.mainloop() b = Button(root, text='Play (game name 1)', command=Game1) b.pack() c.pack() root.mainloop()
方案2:嵌套定义close函数(推荐)
在Game1函数内部定义close,这样它可以直接访问局部的root2,避免全局变量的使用:
from tkinter import Tk, Canvas, Button import pyautogui as p root = Tk() c = Canvas(root, width=400, height=400) def Game1(): root.destroy() root2 = Tk() sx, sy = p.size() root2.attributes('-fullscreen', True) c2 = Canvas(root2, width=sx, height=sy, bg='green') c2.pack() # 嵌套定义close,直接访问局部的root2 def close(event): root2.destroy() root2.bind("<Escape>", close) root2.mainloop() b = Button(root, text='Play (game name 1)', command=Game1) b.pack() c.pack() root.mainloop()
方案3:利用事件对象获取窗口
通过event.widget获取触发事件的窗口组件,直接销毁它:
from tkinter import Tk, Canvas, Button import pyautogui as p root = Tk() c = Canvas(root, width=400, height=400) def close(event): # event.widget就是绑定事件的root2窗口,直接销毁 event.widget.destroy() def Game1(): root.destroy() root2 = Tk() sx, sy = p.size() root2.attributes('-fullscreen', True) c2 = Canvas(root2, width=sx, height=sy, bg='green') c2.pack() root2.bind("<Escape>", close) root2.mainloop() b = Button(root, text='Play (game name 1)', command=Game1) b.pack() c.pack() root.mainloop()
内容的提问来源于stack exchange,提问作者Luca_nl
相关产品推荐
相关产品推荐

