首页 > 解决方案 > 使用字典上的循环定义 tkenentry

问题描述

我是 tkinter 和 OOP 的新手,我正在尝试构建一个使用 for 循环创建条目的 GUI。基本上它应该:

我编写了以下模块:

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()

但我无法弄清楚为什么条目和复选框是依赖的

标签: pythontkintertkinter-entry

解决方案


这是一种方法:

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()

创建一个表示其中一行的类,在类中简单地定义标签、两个条目和检查按钮,创建更新列表的方法和启用按钮的方法。然后在遍历字典的循环中创建这些行并将DataRows 添加到列表中。然后将一个函数分配给将遍历该列表并调用每个数据行上的更新函数的按钮,这将更新列表。


推荐阅读