_tkinter.TclError:Python中的无效命令名
这是我在这个网站的第一次发言,所以我先简单介绍一下自己。我叫托马斯,来自丹麦,我有一个建筑工程的学士学位,正在业余时间学习Python编程。所以,可以说我在编程方面有点笨,希望大家能帮帮我。
我附上了两个程序的图片,这样更容易理解发生了什么。
我在程序中遇到的问题是,当我把任何一个输入框设置为空字符串时,就会出现一个TclError错误。但这个错误只会在我第二次创建“ForsideMenuFrame”或“LastarrangementMenuFrame”这个框架时发生。所以,我觉得这可能和我销毁这些框架有关。我这样做是为了“清理”一下,以便程序运行得更好,或者至少我觉得是这样。输出中显示的信息是:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Thoma\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "C:\Users\Thoma\AppData\Local\Programs\Python\Python311\Lib\site-packages\customtkinter\windows\widgets\ctk_entry.py", line 121, in _textvariable_callback
self._activate_placeholder()
File "C:\Users\Thoma\AppData\Local\Programs\Python\Python311\Lib\site-packages\customtkinter\windows\widgets\ctk_entry.py", line 299, in _activate_placeholder
if self._entry.get() == "" and self._placeholder_text is not None and (self._textvariable is None or self._textvariable == ""):
^^^^^^^^^^^^^^^^^
File "C:\Users\Thoma\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 3109, in get
return self.tk.call(self._w, 'get')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_tkinter.TclError: invalid command name ".!lastarrangementmenuframe.!ctkentry.!entry"
程序并没有崩溃,它仍然按照我想要的方式运行,只是让我觉得烦,我不知道怎么才能避免这个问题。
下面是我的代码副本,图片应该在下面附上。
import customtkinter as ctk
import settings, forside, lastarrangement, tagudformning
class App(ctk.CTk):
def __init__(self):
# Setup
super().__init__(fg_color = settings.BACKGROUND_COLOR)
self.title('Snelaster')
self.geometry('1400x850+50+3')
self._set_appearance_mode('dark')
self.iconbitmap('Snow_flake.ico')
self.resizable(False, False)
# Layout
self.rowconfigure(0, weight = 1, uniform = 'a')
self.rowconfigure(1, weight = 24, uniform = 'a')
self.columnconfigure(0, weight = 1, uniform = 'a')
self.columnconfigure(1, weight = 3, uniform = 'a')
# Dictionary for frames
self.frames = {
'forside_menu': None,
'forside_screen': None,
'forside_header': None,
'lastarrangement_menu': None,
'lastarrangement_screen': None,
'lastarrangement_header': None,
'pulttag_menu': None,
'pulttag_screen': None,
'pulttag_header': None,
'sadeltag_menu': None,
'sadeltag_screen': None,
'sadeltag_header': None}
# Dictionary for StringVars
self.string_vars = {
'entry_sag': ctk.StringVar(),
'entry_sagsnr': ctk.StringVar(),
'entry_initialer': ctk.StringVar(),
'entry_dato': ctk.StringVar()}
# Dictionary for StringVars with tracing
self.traced_string_vars01 = {
'entry_C_t': ctk.StringVar(value = '1.0'),
'combobox_C_top': ctk.StringVar(value = 'Normal'),
'label_C_top': ctk.StringVar(value = 'C_top\t=\t1.00'),
'entry_l_1': ctk.StringVar(value = ''),
'entry_l_2': ctk.StringVar(value = ''),
'entry_h': ctk.StringVar(value = ''),
'label_C_s': ctk.StringVar(value = 'C_s\t=\t1.00'),
'label_C_e': ctk.StringVar(value = 'C_e\t=\t1.00')}
# Start tracing of StringVars
self.start_trace_string_vars01()
# Instance of ButtonFrame
self.button_frame = ButtonFrame(self)
self.forside_button_click()
# Run
self.mainloop()
# Button commands
def forside_button_click(self):
# Change button colors
self.button_frame.forside_button.configure(fg_color = settings.FORSIDEHEADER_FRAME_COLOR_DARK)
self.button_frame.lastarrangement_button.configure(fg_color = settings.LASTARRANGEMENTHEADER_FRAME_COLOR)
self.button_frame.formfaktor_button.configure(fg_color = settings.FORMFAKTORHEADER_FRAME_COLOR)
# Destroying exsisting frames
self.destroy_frames()
# Creating Forside Menu Frame
self.frames['forside_menu'] = forside.ForsideMenuFrame(self,
self.string_vars['entry_sag'],
self.string_vars['entry_sagsnr'],
self.string_vars['entry_initialer'],
self.string_vars['entry_dato'])
# Creating Forside Screen Frame
self.frames['forside_screen'] = forside.ForsideScreenFrame(self)
# Creating Forside Header Frame
self.frames['forside_header'] = forside.ForsideHeaderFrame(self)
def lastarrangement_button_click(self):
# Change button colors
self.button_frame.forside_button.configure(fg_color = settings.FORSIDEHEADER_FRAME_COLOR)
self.button_frame.lastarrangement_button.configure(fg_color = settings.LASTARRANGEMENTHEADER_FRAME_COLOR_DARK)
self.button_frame.formfaktor_button.configure(fg_color = settings.FORMFAKTORHEADER_FRAME_COLOR)
# Destroying exsisting frames
self.destroy_frames()
# Creating Lastarrangement Menu Frame
self.frames['lastarrangement_menu'] = lastarrangement.LastarrangementMenuFrame(self,
self.traced_string_vars01['entry_C_t'],
self.traced_string_vars01['combobox_C_top'],
self.traced_string_vars01['label_C_top'],
self.traced_string_vars01['entry_l_1'],
self.traced_string_vars01['entry_l_2'],
self.traced_string_vars01['entry_h'],
self.traced_string_vars01['label_C_s'],
self.traced_string_vars01['label_C_e'])
# Creating Lastarrangement Screen Frame
self.frames['lastarrangement_screen'] = lastarrangement.LastarrangementScreenFrame(self)
# Creating Lastarrangement Header Frame
self.frames['lastarrangement_header'] = lastarrangement.LastarrangementHeaderFrame(self)
def formfaktor_button_click(self):
# Change button colors
self.button_frame.forside_button.configure(fg_color = settings.FORSIDEHEADER_FRAME_COLOR)
self.button_frame.lastarrangement_button.configure(fg_color = settings.LASTARRANGEMENTHEADER_FRAME_COLOR)
self.button_frame.formfaktor_button.configure(fg_color = settings.FORMFAKTORHEADER_FRAME_COLOR_DARK)
# Destroying exsisting frames
self.destroy_frames()
# Creating Formfaktor Menu Frame
self.frames['pulttag_menu'] = tagudformning.PulttagMenuFrame(self)
# Creating Formfaktor Screen Frame
self.frames['pulttag_screen'] = tagudformning.PulttagScreenFrame(self)
# Creating Formfaktor Header Frame
self.frames['pulttag_header'] = tagudformning.PulttagHeaderFrame(self)
def destroy_frames(self):
for key, value in self.frames.items():
if value is not None:
# Destroying the frame
self.frames[key].destroy()
self.frames[key] = None
def start_trace_string_vars01(self):
for value in self.traced_string_vars01.values():
value.trace('w', self.trace_string_vars01)
def trace_string_vars01(self, *args):
# entry_C_t
C_t = self.traced_string_vars01['entry_C_t'].get()
if len(C_t) == 2 and C_t[0] == '0' and C_t[1] != '.' or len(C_t) > 0 and C_t[0] == '.':
self.traced_string_vars01['entry_C_t'].set('0')
try:
C_t = float(C_t)
if C_t > 1:
self.traced_string_vars01['entry_C_t'].set('1.0')
except ValueError:
if C_t == '':
pass
else:
self.traced_string_vars01['entry_C_t'].set('')
# label_C_top
topografi = self.traced_string_vars01['combobox_C_top'].get()
C_top = 1.00
if topografi == 'Afskærmet':
C_top = 1.25
elif topografi == 'Normal':
C_top = 1.00
elif topografi == 'Vindblæst':
C_top = 0.80
self.traced_string_vars01['label_C_top'].set(f'C_top\t=\t{C_top:.2f}')
# entry l_1
l_1 = self.traced_string_vars01['entry_l_1'].get()
if len(l_1) == 2 and l_1[0] == '0' and l_1[1] != '.' or len(l_1) > 0 and l_1[0] == '.':
self.traced_string_vars01['entry_l_1'].set('')
try:
l_1 = float(l_1)
except ValueError:
if l_1 == '':
pass
else:
self.traced_string_vars01['entry_l_1'].set('')
# entry l_2
l_2 = self.traced_string_vars01['entry_l_2'].get()
if len(l_2) == 2 and l_2[0] == '0' and l_2[1] != '.' or len(l_2) > 0 and l_2[0] == '.':
self.traced_string_vars01['entry_l_2'].set('')
try:
l_2 = float(l_2)
except ValueError:
if l_2 == '':
pass
else:
self.traced_string_vars01['entry_l_2'].set('')
# entry h
h = self.traced_string_vars01['entry_h'].get()
if len(h) == 2 and h[0] == '0' and h[1] != '.' or len(h) > 0 and h[0] == '.':
self.traced_string_vars01['entry_h'].set('')
try:
h = float(h)
except ValueError:
if h == '':
pass
else:
self.traced_string_vars01['entry_h'].set('')
# label C_s
try:
C_s = 1.00
if topografi == 'Afskærmet':
C_s = 1.00
elif 2 * h > l_1:
C_s = 1.00
else:
if l_2 <= 10 * h:
C_s = 1.00
elif l_2 >= 20 * h:
C_s = 1.25
else:
C_s = 1 + 0.025 * ((l_2 - 10 * h) / h)
self.traced_string_vars01['label_C_s'].set(f'C_s\t=\t{C_s:.2f}')
except TypeError:
pass
# label C_e
C_e = C_top * C_s
self.traced_string_vars01['label_C_e'].set(f'C_e\t=\t{C_e:.2f}')
class ButtonFrame(ctk.CTkFrame):
def __init__(self, parent):
# Setup
super().__init__(master = parent,
fg_color = settings.BUTTON_FRAME_COLOR)
self.grid(row = 0, column = 0, sticky = 'nsew')
# Create instance of parent (App)
self.parent = parent
# Layout
self.rowconfigure(0, weight = 1, uniform = 'a')
self.columnconfigure((0,1,2), weight = 1, uniform = 'a')
# Button font
font = ctk.CTkFont(family = settings.FONT_FAMILY,
size = settings.BUTTON_FONT_SIZE,
weight = 'bold')
# Button widgets
self.forside_button = ctk.CTkButton(self,
text = 'Forside',
font = font,
text_color = 'white',
fg_color = settings.FORSIDEHEADER_FRAME_COLOR,
hover_color = settings.FORSIDEHEADER_FRAME_COLOR_DARK,
corner_radius = settings.BUTTON_CORNER_RADIUS,
command = self.parent.forside_button_click)
self.forside_button.grid(row = 0, column = 0,
sticky = 'nsew')
self.lastarrangement_button = ctk.CTkButton(self,
text = 'Lastarrangement',
font = font,
text_color = 'white',
fg_color = settings.LASTARRANGEMENTHEADER_FRAME_COLOR,
hover_color = settings.LASTARRANGEMENTHEADER_FRAME_COLOR_DARK,
corner_radius = settings.BUTTON_CORNER_RADIUS,
command = self.parent.lastarrangement_button_click)
self.lastarrangement_button.grid(row = 0, column = 1,
sticky = 'nsew')
self.formfaktor_button = ctk.CTkButton(self,
text = 'Formfaktor',
font = font,
text_color = 'white',
fg_color = settings.FORMFAKTORHEADER_FRAME_COLOR,
hover_color = settings.FORMFAKTORHEADER_FRAME_COLOR_DARK,
corner_radius = settings.BUTTON_CORNER_RADIUS,
command = self.parent.formfaktor_button_click)
self.formfaktor_button.grid(row = 0, column = 2,
sticky = 'nsew')
if __name__ == '__main__':
App()
这是我尝试过的,但没有成功。在程序开始时,我导入了_tkinter。
import customtkinter as ctk
import settings, forside, lastarrangement, tagudformning
import _tkinter as _tk
然后在App类的trace_string_vars01方法中,我尝试捕获TclError错误,然后忽略它。
# entry_C_t
try:
C_t = self.traced_string_vars01['entry_C_t'].get()
if len(C_t) == 2 and C_t[0] == '0' and C_t[1] != '.' or len(C_t) > 0 and C_t[0] == '.':
self.traced_string_vars01['entry_C_t'].set('0')
try:
C_t = float(C_t)
if C_t > 1:
self.traced_string_vars01['entry_C_t'].set('1.0')
except ValueError:
if C_t == '':
pass
else:
self.traced_string_vars01['entry_C_t'].set('')
except _tk.TclError:
pass
1 个回答
这个错误提示是说问题出在 costumtkinter
这个包里,源代码给了你几个可能出错的地方。
你可以通过把一个变量设置为空字符串,或者使用配置占位符、失去焦点、删除方法,或者通过创建一个新的输入框来解决这个问题。
另外,你的错误是指向这个输入框:
".!lastarrangementmenuframe.!ctkentry.!entry"
虽然你提供了很多代码,但在这种情况下还不够,因为 lastarrangement.LastarrangementMenuFrame
是在一个导入的模块里定义的。
这个错误:
_tkinter.TclError: invalid command name ".!lastarrangementmenuframe.!ctkentry.!entry"
意味着你或者 StringVar
,或者某个事件指向了一个已经不存在的控件。