python - 使用字典上的循环定义 tkenentry
问题描述
我是 tkinter 和 OOP 的新手,我正在尝试构建一个使用 for 循环创建条目的 GUI。基本上它应该:
- 读取字典并将其键用作 tk.Labels
- 使用它的最后两个值作为两个 tkinter 条目的预定义值(每个标签应该有两个 antries)。
- 每个条目都应该有一个复选框,用于禁用/启用每行的第二个条目
- 使用按钮更新字典的值
我编写了以下模块:
import tkinter as tk
def create_input_dictionary():
out = {'Header 1': ['DATA', 'Min', 'Max'],
'Do': ['Lab1', 'mm', '25', '35'],
'Di': ['Lab1', 'mm', '25', '35'],
'nos': ['Lab9', '10']
}
return out
def isfloat(value):
"""The function checks if an element is a number"""
try:
float(value)
return True
except ValueError:
return False
def allarefloats(var_list):
"""The function checks if all the elements in the lists are numbers"""
check = True
for item in var_list:
check = check and isfloat(item)
return check
class gui:
'''this is a classe that creates an instance of the GUI'''
def __init__(self, master): # , container, input_dict): # , *args, **kwargs):
self.master = master
self.ck1 = []
self.ent1 = []
self.ent2 = []
def make_entry(self, container, input_dict):
self.container = container
self.input_dict = input_dict
self.entry_col1 = tk.StringVar()
self.entry_col2 = tk.StringVar()
self.label_entry = tk.StringVar()
self.nac = [tk.IntVar()] * len(input_dict)
for ind, key in enumerate(self.input_dict):
if 'Header' not in key:
n = 0
if key != 'nos':
self.ck1.append(tk.Checkbutton(self.container, variable=self.nac[n], command=lambda: self.naccheck()))
self.ck1[-1].grid(row=ind, column=0, sticky='ns')
n += 1
label = self.input_dict[key][0] + '(' + self.input_dict[key][1] + ')'
tk.Label(self.container, text=label).grid(row=ind, column=1, sticky='nw')
self.ent1.append(
tk.Entry(self.container, width=10, background='white',
textvariable=self.entry_col1, state='normal'))
self.ent1[-1].grid(row=ind, column=2, sticky='ns')
self.ent2.append(tk.Entry(self.container, width=10, background='white',
textvariable=self.entry_col2, state='disabled'))
self.ent2[-1].grid(row=ind, column=3, sticky='ns')
else:
label = self.input_dict[key][0]
tk.Label(self.container, text=label).grid(row=ind, column=0, columnspan=2, sticky='ns')
self.ent1[-1] = tk.Entry(self.container, width=10, background='white',
textvariable=self.entry_col1, state='normal')
self.ent1[-1].grid(row=ind, column=2, columnspan=2, sticky='ns')
def naccheck(self):
if self.nac[-1].get() == 0:
self.ent2[-1].configure(state='disabled')
else:
self.ent2[-1].configure(state='normal')
if __name__ == '__main__':
main_root = tk.Tk()
input_frame = tk.Frame(main_root, padx=10, pady=5)
input_frame.grid(row=0, sticky='ns')
input_steps = tk.Frame(main_root, padx=10, pady=5)
input_steps.grid(row=1, sticky='ns')
button_first_frame = tk.Frame(main_root, padx=10, pady=5)
button_first_frame.grid(row=2, sticky='ns')
dict_inp = create_input_dictionary()
gui = gui(main_root)
gui.make_entry(input_frame, dict_inp)
button = tk.Button(button_first_frame, text="click me", command=lambda: print(dict_inp))
button.grid(row=0, columnspan=3)
main_root.mainloop()
但我无法弄清楚为什么条目和复选框是依赖的
解决方案
这是一种方法:
import tkinter as tk
out = {
'Header 1': ['DATA', 'Min', 'Max'],
'Do': ['Lab1', 'mm', '25', '35'],
'Di': ['Lab1', 'mm', '25', '35'],
'nos': ['Lab9', '10']
}
class DataRow(tk.Frame):
def __init__(self, parent, label, lst, **kwargs):
super().__init__(parent, **kwargs)
self.lst = lst
self.columnconfigure(tuple(range(4)), weight=1, minsize=100)
tk.Label(self, text=label).grid(row=0, column=0, sticky='w')
self.entry1 = tk.Entry(self)
self.entry1.grid(row=0, column=1)
self.entry1.insert('end', lst[-2])
self.entry2 = tk.Entry(self)
self.entry2.grid(row=0, column=3)
self.entry2.insert('end', lst[-1])
self.var = tk.IntVar(master=self, value=1)
self.check = tk.Checkbutton(
self, text='Enabled', command=self.enabled, onvalue=1, offvalue=0,
variable=self.var
)
self.check.grid(row=0, column=2)
def enabled(self):
if self.var.get():
self.entry2.config(state='normal')
else:
self.entry2.config(state='disabled')
def update_data(self):
self.lst[-2:] = self.entry1.get(), self.entry2.get()
def update_dict():
for row in data_rows:
row.update_data()
root = tk.Tk()
data_rows = []
for key, value in out.items():
dr = DataRow(root, key, value)
dr.pack(expand=True, fill='both')
data_rows.append(dr)
tk.Button(
root, text='Update', command=update_dict
).pack(side='bottom', expand=True, fill='both')
root.mainloop()
创建一个表示其中一行的类,在类中简单地定义标签、两个条目和检查按钮,创建更新列表的方法和启用按钮的方法。然后在遍历字典的循环中创建这些行并将DataRow
s 添加到列表中。然后将一个函数分配给将遍历该列表并调用每个数据行上的更新函数的按钮,这将更新列表。
推荐阅读
- sql - 有没有“标准”的主键池表实现方法?
- javascript - 将时刻日期与 Javascript 中的“本机”日期进行比较
- docker - docker中的Flask,访问本地运行的其他flask服务器
- javascript - 跟踪组件内数组更改的最佳方法是什么?
- html - 如何居中引导 jumbotron
- sparql - SPARQL:将多个谓词值组合成标签数组
- python - fractions.Fraction f 字符串作为带有 __format__ 的浮点数
- c# - 绑定到业务逻辑类时如何修复 ArgumentException
- php - 请求明确给定的 IP,但使用明确给定的主机名来进行 SSL 验证?
- php - Drush 允许的内存大小为 2097152 字节已用尽