Python tkinter: error _tkinter.TclError: bad window path name ".!button2"
Python tkinter: error _tkinter.TclError: bad window path name ".!button2"
我正在为我的 python tkinter 程序制作主屏幕,我的切换按钮出现奇怪的错误。
我定义了 2 个函数:第一个叫做 self.do_on()
破坏了关闭按钮并放置了打开按钮。第二个叫做 self.do_off()
破坏了 on 按钮并放置了 off 按钮。
默认放置关闭按钮。
程序成功执行了self.do_off()
函数,并在按下关闭按钮时将关闭按钮变为打开按钮。但是当我按下已经放置的一个按钮时,它只会破坏打开按钮并且 returns 一个错误。
程序如下:
from tkinter import *
from tkinter import ttk
import tkinter as tk
import time
def isNumber():
try:
int(root.enteredTime)
return True
except ValueError:
return False
def callback1(var, index, mode):
root.enteredTime = str(root.entryTime.get()).replace(":", "")
if isNumber() == False:
print(root.changes)
print(root.changes[-1])
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.changes[-1])
else:
if len(root.enteredTime) <= 2:
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.enteredTime)
root.entryTime.insert('end', ':')
if len(root.enteredTime) == 4:
root.enteredTimeO = root.entryTime.get()
if len(root.enteredTime) >= 4:
root.focus()
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.enteredTimeO)
root.adds = root.adds +1
root.changes.append(str(root.entryTime.get()))
class root(Tk):
def __init__(self):
super(root, self).__init__()
self.off = PhotoImage(file = "OFF.png")
self.on = PhotoImage(file = "ON.png")
self.title("Chess Clock")
self.minsize(1539,800)
#self.wm_iconbitmap(r"")
self.windowBG = '#313131'
self.state('zoomed')
self.configure(bg=self.windowBG)
self.adds = 0
self.changes = []
self.createHomeScreen()
def do_off(self):
self.onBtn.destroy()
self.offBtn.place(x=900, y=390)
def do_on(self):
self.offBtn.destroy()
self.onBtn.place(x=900, y=390)
def createHomeScreen(self):
self.bg2 = Label(self, width=185, height=45, bg='#252525')
self.bg2.place(x=120, y=85)
Label(self, text='Time per player:', bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold").place(x=170, y=140)
Label(self, text='Extra Seconds:', bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold").place(x=170, y=240)
Label(self, text='Extra Seconds are added every move.', bg='#252525', fg='#656565', font ="Gadugi 15").place(x=185, y=300)
Label(self, text='Sound Notifications:', bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold").place(x=170, y=380)
Label(self, text='A sound notification will be emitted when clock is switched from a player to another one, when there is 30 or 10 seconds left ', bg='#252525', fg='#656565', font ="Gadugi 15").place(x=185, y=475)
Label(self, text='and also when the game is over.', bg='#252525', fg='#656565', font ="Gadugi 15").place(x=185, y=500)
self.setTime = StringVar()
self.entryTime = Entry(self, width=5, textvariable = self.setTime, font="Gadugi 30", background='#252525', fg='white', justify='center', insertbackground='white', borderwidth = 0, highlightthickness = 0)
self.entryTime.place(x=1000, y=140)
self.entryTime.focus()
self.setTime.trace_add("write", callback1)
self.onBtn = Button(self, image=self.on, bd=0, borderwidth = 0, highlightthickness = 0, command=self.do_off)
self.offBtn = Button(self, image=self.off, bd=0, borderwidth = 0, highlightthickness = 0, command=self.do_on)
self.offBtn.place(x=900, y=390)
root=root()
root.mainloop()
错误如下:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "d:\Users\Jean Paul\OneDrive\Programming\Programs\Prog 6 - Chess Clock\test.py", line 56, in do_off
self.offBtn.place(x=900, y=390)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 2448, in place_configure
self.tk.call(
_tkinter.TclError: bad window path name ".!button2"
这是关闭和打开按钮的图片:
ON.png
:
OFF.png
:
此处问题中发布的代码在评论中建议更改为 .destroy()
替换为 .place_forget()
。这解决了所描述的问题:
#
from tkinter import Tk, PhotoImage, Label, StringVar, Entry, Button
import time
def isNumber():
try:
int(root.enteredTime)
return True
except ValueError:
return False
def callback1(var, index, mode):
root.enteredTime = str(root.entryTime.get()).replace(":", "")
if isNumber() == False:
print(root.changes)
print(root.changes[-1])
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.changes[-1])
else:
if len(root.enteredTime) <= 2:
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.enteredTime)
root.entryTime.insert('end', ':')
if len(root.enteredTime) == 4:
root.enteredTimeO = root.entryTime.get()
if len(root.enteredTime) >= 4:
root.focus()
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.enteredTimeO)
root.adds = root.adds +1
root.changes.append(str(root.entryTime.get()))
class root(Tk):
def __init__(self):
super(root, self).__init__()
self.off = PhotoImage(file = "OFF.png")
self.on = PhotoImage(file = "ON.png")
self.title("Chess Clock")
self.minsize(1725,800)
# self.wm_iconbitmap(r"")
self.windowBG = '#313131'
# self.state('zoomed') # gives an error
self.state('normal')
self.configure(bg=self.windowBG)
self.adds = 0
self.changes = []
self.createHomeScreen()
def do_off(self):
self.onBtn.place_forget() # stop to show the placed button
# self.onBtn.destroy() will make the button unavailable
self.offBtn.place(x=900, y=390)
def do_on(self):
self.offBtn.place_forget() # stop to show the placed button
self.onBtn.place(x=900, y=390)
def createHomeScreen(self):
self.bg2 = Label(self, width=185, height=45, bg='#252525')
self.bg2.place(x=120, y=85)
Label(self, text='Time per player:',
bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold" ).place(x=170, y=140)
Label(self, text='Extra Seconds:',
bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold" ).place(x=170, y=240)
Label(self, text='Extra Seconds are added every move.',
bg='#252525', fg='#656565', font ="Gadugi 15" ).place(x=185, y=300)
Label(self, text='Sound Notifications:',
bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold" ).place(x=170, y=380)
Label(self, text='A sound notification will be emitted when clock is switched from a player to another one, when there is 30 or 10 seconds left ',
bg='#252525', fg='#656565', font ="Gadugi 11" ).place(x=185, y=475)
Label(self, text='and also when the game is over.',
bg='#252525', fg='#656565', font ="Gadugi 15" ).place(x=185, y=500)
self.setTime = StringVar()
self.entryTime = Entry(self, width=5, textvariable = self.setTime,
font="Gadugi 30", background='#252525', fg='white', justify='center',
insertbackground='white', borderwidth = 0, highlightthickness = 0)
self.entryTime.place(x=1000, y=140)
self.entryTime.focus()
self.setTime.trace_add("write", callback1)
self.onBtn = Button(self, image=self.on, bd=0, borderwidth = 0, highlightthickness = 0, command=self.do_off)
self.offBtn = Button(self, image=self.off, bd=0, borderwidth = 0, highlightthickness = 0, command=self.do_on)
self.offBtn.place(x=900, y=390)
root=root()
root.mainloop()
我正在为我的 python tkinter 程序制作主屏幕,我的切换按钮出现奇怪的错误。
我定义了 2 个函数:第一个叫做 self.do_on()
破坏了关闭按钮并放置了打开按钮。第二个叫做 self.do_off()
破坏了 on 按钮并放置了 off 按钮。
默认放置关闭按钮。
程序成功执行了self.do_off()
函数,并在按下关闭按钮时将关闭按钮变为打开按钮。但是当我按下已经放置的一个按钮时,它只会破坏打开按钮并且 returns 一个错误。
程序如下:
from tkinter import *
from tkinter import ttk
import tkinter as tk
import time
def isNumber():
try:
int(root.enteredTime)
return True
except ValueError:
return False
def callback1(var, index, mode):
root.enteredTime = str(root.entryTime.get()).replace(":", "")
if isNumber() == False:
print(root.changes)
print(root.changes[-1])
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.changes[-1])
else:
if len(root.enteredTime) <= 2:
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.enteredTime)
root.entryTime.insert('end', ':')
if len(root.enteredTime) == 4:
root.enteredTimeO = root.entryTime.get()
if len(root.enteredTime) >= 4:
root.focus()
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.enteredTimeO)
root.adds = root.adds +1
root.changes.append(str(root.entryTime.get()))
class root(Tk):
def __init__(self):
super(root, self).__init__()
self.off = PhotoImage(file = "OFF.png")
self.on = PhotoImage(file = "ON.png")
self.title("Chess Clock")
self.minsize(1539,800)
#self.wm_iconbitmap(r"")
self.windowBG = '#313131'
self.state('zoomed')
self.configure(bg=self.windowBG)
self.adds = 0
self.changes = []
self.createHomeScreen()
def do_off(self):
self.onBtn.destroy()
self.offBtn.place(x=900, y=390)
def do_on(self):
self.offBtn.destroy()
self.onBtn.place(x=900, y=390)
def createHomeScreen(self):
self.bg2 = Label(self, width=185, height=45, bg='#252525')
self.bg2.place(x=120, y=85)
Label(self, text='Time per player:', bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold").place(x=170, y=140)
Label(self, text='Extra Seconds:', bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold").place(x=170, y=240)
Label(self, text='Extra Seconds are added every move.', bg='#252525', fg='#656565', font ="Gadugi 15").place(x=185, y=300)
Label(self, text='Sound Notifications:', bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold").place(x=170, y=380)
Label(self, text='A sound notification will be emitted when clock is switched from a player to another one, when there is 30 or 10 seconds left ', bg='#252525', fg='#656565', font ="Gadugi 15").place(x=185, y=475)
Label(self, text='and also when the game is over.', bg='#252525', fg='#656565', font ="Gadugi 15").place(x=185, y=500)
self.setTime = StringVar()
self.entryTime = Entry(self, width=5, textvariable = self.setTime, font="Gadugi 30", background='#252525', fg='white', justify='center', insertbackground='white', borderwidth = 0, highlightthickness = 0)
self.entryTime.place(x=1000, y=140)
self.entryTime.focus()
self.setTime.trace_add("write", callback1)
self.onBtn = Button(self, image=self.on, bd=0, borderwidth = 0, highlightthickness = 0, command=self.do_off)
self.offBtn = Button(self, image=self.off, bd=0, borderwidth = 0, highlightthickness = 0, command=self.do_on)
self.offBtn.place(x=900, y=390)
root=root()
root.mainloop()
错误如下:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "d:\Users\Jean Paul\OneDrive\Programming\Programs\Prog 6 - Chess Clock\test.py", line 56, in do_off
self.offBtn.place(x=900, y=390)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 2448, in place_configure
self.tk.call(
_tkinter.TclError: bad window path name ".!button2"
这是关闭和打开按钮的图片:
ON.png
:
OFF.png
:
此处问题中发布的代码在评论中建议更改为 .destroy()
替换为 .place_forget()
。这解决了所描述的问题:
#
from tkinter import Tk, PhotoImage, Label, StringVar, Entry, Button
import time
def isNumber():
try:
int(root.enteredTime)
return True
except ValueError:
return False
def callback1(var, index, mode):
root.enteredTime = str(root.entryTime.get()).replace(":", "")
if isNumber() == False:
print(root.changes)
print(root.changes[-1])
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.changes[-1])
else:
if len(root.enteredTime) <= 2:
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.enteredTime)
root.entryTime.insert('end', ':')
if len(root.enteredTime) == 4:
root.enteredTimeO = root.entryTime.get()
if len(root.enteredTime) >= 4:
root.focus()
root.entryTime.delete(0,'end')
root.entryTime.insert('end', root.enteredTimeO)
root.adds = root.adds +1
root.changes.append(str(root.entryTime.get()))
class root(Tk):
def __init__(self):
super(root, self).__init__()
self.off = PhotoImage(file = "OFF.png")
self.on = PhotoImage(file = "ON.png")
self.title("Chess Clock")
self.minsize(1725,800)
# self.wm_iconbitmap(r"")
self.windowBG = '#313131'
# self.state('zoomed') # gives an error
self.state('normal')
self.configure(bg=self.windowBG)
self.adds = 0
self.changes = []
self.createHomeScreen()
def do_off(self):
self.onBtn.place_forget() # stop to show the placed button
# self.onBtn.destroy() will make the button unavailable
self.offBtn.place(x=900, y=390)
def do_on(self):
self.offBtn.place_forget() # stop to show the placed button
self.onBtn.place(x=900, y=390)
def createHomeScreen(self):
self.bg2 = Label(self, width=185, height=45, bg='#252525')
self.bg2.place(x=120, y=85)
Label(self, text='Time per player:',
bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold" ).place(x=170, y=140)
Label(self, text='Extra Seconds:',
bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold" ).place(x=170, y=240)
Label(self, text='Extra Seconds are added every move.',
bg='#252525', fg='#656565', font ="Gadugi 15" ).place(x=185, y=300)
Label(self, text='Sound Notifications:',
bg='#252525', fg='#AAA4A6', font ="Gadugi 30 bold" ).place(x=170, y=380)
Label(self, text='A sound notification will be emitted when clock is switched from a player to another one, when there is 30 or 10 seconds left ',
bg='#252525', fg='#656565', font ="Gadugi 11" ).place(x=185, y=475)
Label(self, text='and also when the game is over.',
bg='#252525', fg='#656565', font ="Gadugi 15" ).place(x=185, y=500)
self.setTime = StringVar()
self.entryTime = Entry(self, width=5, textvariable = self.setTime,
font="Gadugi 30", background='#252525', fg='white', justify='center',
insertbackground='white', borderwidth = 0, highlightthickness = 0)
self.entryTime.place(x=1000, y=140)
self.entryTime.focus()
self.setTime.trace_add("write", callback1)
self.onBtn = Button(self, image=self.on, bd=0, borderwidth = 0, highlightthickness = 0, command=self.do_off)
self.offBtn = Button(self, image=self.off, bd=0, borderwidth = 0, highlightthickness = 0, command=self.do_on)
self.offBtn.place(x=900, y=390)
root=root()
root.mainloop()