我决定尝试使用类来重新创建游戏,这样我就不必使用全局变量,但是在尝试运行游戏时出现错误。
Traceback (most recent call last): File "D:\Users\James\Desktop\botmod OOP\index.py", line 203, in <module> Game.New_Game(Root) File "D:\Users\James\Desktop\botmod OOP\index.py", line 18, in New_Game Play_Button = self.Start_Canvas.create_window(300, 325, window = Play_Button) File "C:\Users\James\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py">, line 2501, in create_window return self._create('window', args, kw) File "C:\Users\James\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py">, line 2474, in _create *(args + self._options(cnf, kw))))
_tkinter.TclError: bad window path name ".!button"
我已尽力查看了此内容,无法独自锻炼错误所在。下面是我的代码,如果需要的话,我可以提供所有代码。它应该创建一个Tkinter按钮,然后将其应用于 Canvas ,但是它给了我上面的错误。
def New_Game(self, Root):
self.Start_Canvas = Canvas(Root, width = 600, height = 500, bd=0, highlightthickness=0, bg = '#ffffff')
self.Start_Canvas.pack()
Title = self.Start_Canvas.create_text(300, 163, text = "BOTMOD", font = ('Cinema Gothic BTN Shadow', 75, 'normal'))
Gen_PButton = Button(text = "PLAY", width = 10, font=('Arial', 15), command = self.Play_Game)
Play_Button = self.Start_Canvas.create_window(300, 325, window = Gen_PButton)
Gen_EButton = Button(text = "EXIT", width = 10, font=('Arial', 15), command = lambda: self.Game_End("EXIT"))
Exit_Button = self.Start_Canvas.create_window(300, 375, window = Gen_EButton)
在使用oop之前,它使用了全局变量和函数,因此在定义按钮时我找不到导致问题的原因。
示例代码如下
from tkinter import *
from random import choice, shuffle
class Game:
def __init__(self):
self.Playing_Game = True
self.Game_Paused = False
self.Restart_Game = False
self.Already_Played = False
def New_Game(self, Root):
self.Start_Canvas = Canvas(Root, width = 600, height = 500, bd=0, highlightthickness=0, bg = '#ffffff')
self.Start_Canvas.pack()
Title = self.Start_Canvas.create_text(300, 163, text = "BOTMOD", font = ('Cinema Gothic BTN Shadow', 75, 'normal'))
Gen_PButton = Button(text = "PLAY", width = 10, font=('Arial', 15), command = self.Play_Game)
Play_Button = self.Start_Canvas.create_window(300, 325, window = Gen_PButton)
Gen_EButton = Button(text = "EXIT", width = 10, font=('Arial', 15), command = lambda: self.Game_End("EXIT"))
Exit_Button = self.Start_Canvas.create_window(300, 375, window = Gen_EButton)
def Play_Game(self):
if self.Already_Played == False:
self.Start_Canvas.destroy()
self.Menu_Canvas = Canvas(Root, width = 600, height = 500, bd=0, highlightthickness=0, bg = '#C0C0C0')
self.Menu_Canvas.pack()
def Game_End(self):
if self.End_Option == "EXIT":
self.Playing_Game = False
Root.destroy()
else:
self.Game_Finished = True
self.Game_Canvas.create_rectangle(120, 120, 480, 300, fill = "#ffffff")
self.Game_Canvas.create_text(300, 210, text = End_Option, font = ('Abadi', 35, "bold"))
#Continue_Button = Button(Root, text = 'Continue', command = self.Game_Restart)
Exit_Button = Button(Root, text = 'Exit', command = lambda: self.Game_End('EXIT'))
#Continue_Button.pack()
Exit_Button.pack()
Root = Tk()
Game = Game()
while True:
while Game.Restart_Game == False:
if Game.Playing_Game == False:
break
else:
Game_Finished = False
Root = Tk()
if Game.Already_Played == True:
Game.Play_Game()
Root.mainloop()
elif Game.Already_Played == False:
Game.New_Game(Root)
Root.mainloop()
break
最佳答案
迫在眉睫的问题是,您还没有为按钮赋予父项。 tl; dr是您只需将Root
(或其他一些合适的父窗口)添加到Gen_Pbutton
和Gen_EButton
的构造函数中,就像对所有其他小部件一样。
以下两行有重要区别:
Gen_PButton = Button(Root, text = "PLAY", width = 10, font=('Arial', 15), command = self.Play_Game)
Gen_PButton = Button(text = "PLAY", width = 10, font=('Arial', 15), command = self.Play_Game)
这两个版本都为按钮小部件(在这种情况下为
.!button
)创建了一个新名称,并创建了与该名称相关联的新tkinter.Button
对象,但是第一个版本也要求Root
创建名为.!button
的实际小部件,而第二个版本不要求任何人创建小部件。因此,您最终得到了一个附加到不存在的小部件的Button
对象,每当您尝试使用该Button
对象时,都会出现如下错误:_tkinter.TclError: bad window path name ".!button"
发生此类错误的常见原因是,您已破坏了底层按钮小部件,但继续尝试使用
Button
。但是在这种情况下,您根本不会首先创建窗口小部件,这显然会导致相同的问题。要确切了解幕后情况,您必须了解Tkinter的工作原理-实际的GUI小部件和窗口由代码以完全不同的语言Tcl/Tk管理,tkinter是Python对象与Tcl对象的名称和关联。将您的每个方法调用代理到这些Tcl对象。
您可能想知道为什么tkinter首先让您摆脱了这种构造,而不是给您一个更容易理解的错误(前一行),像这样:
_tkinter.TclError: trying to create ".!button" with null parent
好吧,从技术上讲,这是完全合法的。您可以稍后通过一些较低层的方法来创建该Tcl小部件,或者您可能已经创建了该Tcl小部件,现在只想在其周围包装tkinter Controller 。两者都是非常罕见的情况,但是它们并不是荒谬的,因此tkinter允许它们。
而且,更重要的是:您真的会更容易地理解“更好”的错误消息吗?当您初次学习tkinter时,这两个都没有意义,而且都是可以学习理解和处理的东西。
关于python - 我收到错误_tkinter.TclError : bad window path name ".!button" and i'm not sure why,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49825857/