自定义 tkinter 跟踪延迟
我在使用自定义的tkinter时遇到了一些性能问题,这主要是因为trace方法的原因。我在一个叫做App的类里有一个trace方法,它会追踪我所有的StringVars(字符串变量)。同时,我还有一个方法用来记录当前打开的是哪个标签(‘Forside’,‘Lastarrangement’,‘Pulttag’,‘Sadeltag’),这样trace方法就只会追踪与当前标签相关的StringVars。你可以看看我附上的图片。
我的问题是,如果某个标签下的StringVars太多,比如我这个‘Sadeltag’标签下的StringVars数量比较多,程序就会变得很卡。我个人觉得‘Sadeltag’标签下需要追踪的9个StringVars并不算多,但对我的程序来说似乎就是太多了。不过,我还是个新手,对编程的理解还很浅。
所以,我想问的是,这对于一个自定义的tkinter应用来说是不是太复杂了,还是说我的代码结构设计上有一些大的问题?
我希望这个应用能够在变量值变化时动态更新。
def trace_string_vars(self, *args):
for tab in self.current_state.keys():
# Tracing Forside
if tab == 'Forside' and self.current_state[tab]:
pass
# Tracing Lastarrangement
elif tab == 'Lastarrangement' and self.current_state[tab]:
# entry_C_t
C_t = self.string_vars['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.string_vars['entry_C_t'].set('0')
try:
C_t = float(C_t)
if C_t > 1:
self.string_vars['entry_C_t'].set('1.0')
except ValueError:
self.string_vars['entry_C_t'].set('')
# label_C_top
topografi = self.string_vars['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.string_vars['label_C_top'].set(f'C_top\t=\t{C_top:.2f}')
self.string_vars['label_C_top_screen'].set(f'\t\t{topografi} \t\u21D2\tC_top = {C_top:.2f}')
# entry l_1
l_1 = self.string_vars['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.string_vars['entry_l_1'].set('')
try:
l_1 = float(l_1)
except ValueError:
self.string_vars['entry_l_1'].set('')
# entry l_2
l_2 = self.string_vars['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.string_vars['entry_l_2'].set('')
try:
l_2 = float(l_2)
except ValueError:
self.string_vars['entry_l_2'].set('')
# entry h
h = self.string_vars['entry_h'].get()
if len(h) == 2 and h[0] == '0' and h[1] != '.' or len(h) > 0 and h[0] == '.':
self.string_vars['entry_h'].set('')
try:
h = float(h)
except ValueError:
self.string_vars['entry_h'].set('')
# label C_s
try:
C_s = 1.00
if topografi == 'Afskærmet':
C_s = 1.00
self.string_vars['label_C_s_screen'].set(f'\t\t{topografi}\t\u21D2\tC_s = 1.00')
elif 2 * h > l_1:
C_s = 1.00
self.string_vars['label_C_s_screen'].set('\t\t2 \u2022 h > l_1\t\t\u21D2\tC_s = 1.00')
else:
if l_2 <= 10 * h:
C_s = 1.00
self.string_vars['label_C_s_screen'].set('\t\t2 \u2022 h \u2264 l_1\t\tog\tl_2 \u2264 10 \u2022 h\t\u21D2\tC_s = 1.00')
elif l_2 >= 20 * h:
C_s = 1.25
self.string_vars['label_C_s_screen'].set('\t\t2 \u2022 h \u2264 l_1\t\tog\tl_2 \u2265 20 \u2022 h\t\u21D2\tC_s = 1.25')
else:
C_s = 1 + 0.025 * ((l_2 - 10 * h) / h)
self.string_vars['label_C_s_screen'].set(f'\t\t2 \u2022 h \u2264 l_1\t\tog\t10 \u2022 h < l_2 < 20 \u2022 h\t\t\u21D2\tC_s = 1 + 0.025 \u2022 ((l_2 - 10 \u2022 h) / h) = {C_s:.2f}')
self.string_vars['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.string_vars['label_C_e'].set(f'C_e\t=\t{C_e:.2f}')
# Tracing Formfaktor
elif tab == 'Tagudformning' and self.current_state['Forside'] == False:
if tab == 'Tagudformning' and self.current_state['Lastarrangement'] == False:
for tagtype in self.current_state[tab].keys():
# Tracing Pulttag
if tagtype == 'Pulttag' and self.current_state[tab][tagtype]:
# Tagtype
self.tagudformning = self.string_vars['combobox_tagtype'].get()
if self.tagudformning in settings.TAGUDFORMNING_LIST:
self.formfaktor_button_click()
# Brystværn
brystværn = self.pulttag_menu_frame.switch_bryst_pult.get()
if brystværn == 1:
self.string_vars['switch_bryst_pult'].set('Ja')
elif brystværn == 0:
self.string_vars['switch_bryst_pult'].set('Nej')
# entry_a_pult
a_pult = self.string_vars['entry_a_pult'].get()
if len(a_pult) == 2 and a_pult[0] == '0' and a_pult[1] != '.' or len(a_pult) > 0 and a_pult[0] == '.':
self.string_vars['entry_a_pult'].set('0')
try:
a_pult = float(a_pult)
if a_pult > 90:
self.string_vars['entry_a_pult'].set('90.0')
except ValueError:
self.string_vars['entry_a_pult'].set('')
# label_u_pult
try:
if a_pult <= 30 or brystværn == 1:
u_pult = 0.80
elif a_pult >= 60:
u_pult = 0.00
else:
u_pult = 0.8 * (60 - a_pult) / 30
self.string_vars['label_u_pult'].set(f'\u03BC_1\t=\t{u_pult:.2f}')
except TypeError:
pass
# label_s_pult
try:
C_t = self.string_vars['entry_C_t'].get()
C_t = float(C_t)
C_e = self.string_vars['label_C_e'].get()[-4:]
C_e = float(C_e)
u_pult = self.string_vars['label_u_pult'].get()[-4:]
u_pult = float(u_pult)
s_pult = u_pult * C_e * C_t * 1
self.string_vars['label_s_pult'].set(f's\t=\t{s_pult:.2f} kN/m\u00B2')
except TypeError:
pass
# canvas_pult01
self.update_canvas_pult01()
self.update_canvas_pult02()
# Tracing Sadeltag
elif tagtype == 'Sadeltag' and self.current_state[tab][tagtype]:
# Tagtype
self.tagudformning = self.string_vars['combobox_tagtype'].get()
if self.tagudformning in settings.TAGUDFORMNING_LIST:
self.formfaktor_button_click()
# Brystværn
brystværn_v = self.sadeltag_menu_frame.switch_bryst_sadel_v.get()
if brystværn_v == 1:
self.string_vars['switch_bryst_sadel_v'].set('Ja')
elif brystværn_v == 0:
self.string_vars['switch_bryst_sadel_v'].set('Nej')
brystværn_h = self.sadeltag_menu_frame.switch_bryst_sadel_h.get()
if brystværn_h == 1:
self.string_vars['switch_bryst_sadel_h'].set('Ja')
elif brystværn_h == 0:
self.string_vars['switch_bryst_sadel_h'].set('Nej')
# entry_a_pult
a_sadel_v = self.string_vars['entry_a_sadel_v'].get()
if len(a_sadel_v) == 2 and a_sadel_v[0] == '0' and a_sadel_v[1] != '.' or len(a_sadel_v) > 0 and a_sadel_v[0] == '.':
self.string_vars['entry_a_sadel_v'].set('0')
try:
a_sadel_v = float(a_sadel_v)
if a_sadel_v > 90:
self.string_vars['entry_a_sadel_v'].set('90.0')
except ValueError:
self.string_vars['entry_a_sadel_v'].set('')
a_sadel_h = self.string_vars['entry_a_sadel_h'].get()
if len(a_sadel_h) == 2 and a_sadel_h[0] == '0' and a_sadel_h[1] != '.' or len(a_sadel_h) > 0 and a_sadel_h[0] == '.':
self.string_vars['entry_a_sadel_h'].set('0')
try:
a_sadel_h = float(a_sadel_h)
if a_sadel_h > 90:
self.string_vars['entry_a_sadel_h'].set('90.0')
except ValueError:
self.string_vars['entry_a_sadel_h'].set('')
# label_u_pult
try:
if a_sadel_v <= 30 or brystværn_v == 1:
u_sadel_v = 0.80
elif a_sadel_v >= 60:
u_sadel_v = 0.00
else:
u_sadel_v = 0.8 * (60 - a_sadel_v) / 30
self.string_vars['label_u_sadel_v'].set(f'\u03BC_1\t=\t{u_sadel_v:.2f}')
except TypeError:
pass
try:
if a_sadel_h <= 30 or brystværn_h == 1:
u_sadel_h = 0.80
elif a_sadel_h >= 60:
u_sadel_h = 0.00
else:
u_sadel_h = 0.8 * (60 - a_sadel_h) / 30
self.string_vars['label_u_sadel_h'].set(f'\u03BC_2\t=\t{u_sadel_h:.2f}')
except TypeError:
pass
# label_s_pult
try:
C_t = self.string_vars['entry_C_t'].get()
C_t = float(C_t)
C_e = self.string_vars['label_C_e'].get()[-4:]
C_e = float(C_e)
u_sadel_v = self.string_vars['label_u_sadel_v'].get()[-4:]
u_sadel_v = float(u_sadel_v)
s_sadel_v = u_sadel_v * C_e * C_t * 1
self.string_vars['label_s_sadel_v'].set(f's_1\t=\t{s_sadel_v:.2f} kN/m\u00B2')
except TypeError:
pass
try:
C_t = self.string_vars['entry_C_t'].get()
C_t = float(C_t)
C_e = self.string_vars['label_C_e'].get()[-4:]
C_e = float(C_e)
u_sadel_h = self.string_vars['label_u_sadel_h'].get()[-4:]
u_sadel_h = float(u_sadel_h)
s_sadel_h = u_sadel_h * C_e * C_t * 1
self.string_vars['label_s_sadel_h'].set(f's_2\t=\t{s_sadel_h:.2f} kN/m\u00B2')
except TypeError:
pass
我只附上了追踪StringVars的方法,因为我觉得问题可能出在这里。
1 个回答
1
我现在知道我之前做错了什么。我有一些输入框(entry widgets),它们和标签框(label widgets)连接在一起。我用了一种叫做trace的方法来跟踪它们。结果是,这个方法本来应该只运行一次,但实际上却运行了两次。因为我设置了很多这样的输入框和标签框,所以效率变得很低下。后来,我改用了configure方法来更新标签框,现在效果好多了。