[英]How to prevent global variables in Tkinter?
如标题所述,如何防止在 Tkinter 中使用全局变量? 我已经开始学习 Tkinter,并且几乎在我的所有项目中都遇到了问题。 我遇到的问题是大多数小部件需要相互交互,从而产生很多依赖关系。 下面是我的一个有这个问题的项目的代码。 我包含了这个项目的所有代码,因为问题出现在整个代码中。
以apply_filter 函数为例。 为了接收来自用户的输入,Apply Filter 按钮的命令功能需要访问输入字段。 解决此问题的一种方法是将所有输入字段作为参数传递给命令函数。 但是,我不喜欢这个选项,因为这意味着我要么必须将所有代码放在巨大的块中,使代码更难阅读,要么必须通过多个函数传递它,从而导致相同的结果。 我在这里选择的选项是使输入全局化,以便我可以从代码中的任何位置访问它们。 至少代码更容易阅读。 当然,这可能不是一个好的解决方案。 当 GUI 扩展时,这将产生大量的依赖关系,很容易导致错误。
长话短说,我想知道:有没有更好的方法来处理这些依赖关系,这样我就不需要创建大量的全局变量或创建不可读的代码? 预先感谢您所做的任何努力。
import tkinter as tk
from tkinter import filedialog as fd
import pandas as pd
import numpy as np
import sys
start_filter_row = 0
start_filter_column = 0
data_location = ""
df = None
root = None
filterr = {"customercode":{"column name": "Customer (code)", "value": None, "row_number": start_filter_row},
"partnr":{"column name": "Part nr", "value": None, "row_number": start_filter_row + 1},
"partclass":{"column name": "Part class", "value": None, "row_number": start_filter_row + 2},
"partfamily":{"column name": "Part familiy", "value": None, "row_number": start_filter_row + 3},
"startdate":{"column name": "Transaction date", "value": None, "row_number": start_filter_row + 4},
"enddate":{"column name": "Transaction date", "value": None, "row_number": start_filter_row + 5}
}
inputs = dict()
'''
Load Data
'''
def load_dataset():
global df
root.update()
database_location = fd.askopenfilename()
df = load_data(database_location)
def load_data(database_location):
try:
df = pd.read_pickle(database_location)
return df
except Exception as e:
print("Data location not set!", e)
root.destroy()
sys.exit()
'''
create Widgets
'''
def create_filter_inputs():
for key, value in filterr.items():
label = tk.Label(root, text = key)
label.grid(row = value["row_number"], column = start_filter_column, sticky = "w")
entry = tk.Entry(root)
entry.focus_set()
entry.grid(row = value["row_number"], column = start_filter_column + 1, sticky = "w")
inputs[key] = entry
def create_filter_buttons():
apply_button = tk.Button(root, text = "Apply Filter", command = apply_filter)
apply_button.grid(row = start_filter_row + len(filterr), column = 0, sticky = "news")
clear_button = tk.Button(root, text = "Clear Filter", command = clear_filter)
clear_button.grid(row = start_filter_row + len(filterr), column = 1, sticky = "news")
'''
Button functions
'''
def clear_filter():
for key, entry in inputs.items():
entry.delete(0, 'end')
apply_filter()
def apply_filter():
for key, entry in inputs.items():
filterr[key]["value"] = entry.get().split(";")
def main():
global data_location, root
'''
Setting up Tkinter Frame and loading dataset
'''
root = tk.Tk()
root.title("Data Tool V0.1")
loading_label = tk.Label(root, text = "Loading...", width = 30, height = 5)
loading_label.pack()
load_dataset()
loading_label.destroy()
n_rows, n_cols = (4, 3)
root.columnconfigure(tuple(range(n_cols)), weight=1)
root.rowconfigure(tuple(range(n_rows)), weight=1)
'''
Setting up GUI
'''
create_filter_inputs()
create_filter_buttons()
root.mainloop()
if __name__ == "__main__":
main()
您可以通过将 GUI 转换为类格式并将它们设为类变量来避免使用全局变量。
class GUI:
def __init__():
.....
self.myvariable = ...
def function():
newvar = self.myvariable - 5
还值得注意的是,在函数外部定义的变量可以从函数内部看到,反之则不行:
>>> def f(a):
... print(a)
...
>>> b=2
>>> f(b)
2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.