由于跟踪方法,我对自定义 tkinter 的性能有一些问题。我在类 App 中有一个跟踪方法,可以跟踪我的所有 StringVars。但我还有一个方法可以跟踪打开的选项卡(“Forside”、“Lastarrangement”、“Pulttag”、“Sadeltag”),因此跟踪方法仅跟踪附加到相应选项卡的 StringVars。请参阅我附加到此问题的屏幕截图。
我的问题是,如果其中一个选项卡(在我的例子中是“Sadeltag”选项卡)有太多 StringVar,那么程序就会严重滞后。
就我个人而言,我认为程序需要在“Sadeltag”选项卡中跟踪的 9 个 StringVar 并不多,但显然对于我的程序来说确实如此。但再说一次,我有点菜鸟,而且我只触及了编程世界的表面。
所以,我的问题:对于自定义 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 的方法,因为我相信我的问题就在那里发生。
我现在知道我做错了什么了。我有连接到标签小部件的条目小部件。我用trace方法追踪了它们。因此,该方法不再只运行一次,而是运行两次。许多条目小部件和标签小部件都以这种方式设置,这当然会变得非常低效。因此,我用配置方法更新了标签小部件,现在它的性能好多了。