【问题标题】:Update dictionary values using tkinter entries via bind method通过绑定方法使用 tkinter 条目更新字典值
【发布时间】:2021-12-11 19:08:24
【问题描述】:

应该更新字典值的基于 Tkinter 的 GUI。运行正常,还有两个问题:

  1. 为了更新输入值,我使用了bind 方法,即object.bind("<Key>", self._accept),它只适用于 Enter 键,其他键打印之前的值插入条目 [已解决]
  2. 当相应的复选框被停用时,我不知道如何设置entry_c2=entry_c1
import tkinter as tk

def create_input_dictionary():
    out = {'Header': ['LLL', 'Min', 'Max'],
           'Do': ['l1', 'mm', '25', '35'],
           'Di': ['l2', 'mm', '19', '29'],
           'tt': ['l3', 'mm', '0.8', '1.2'],
           'y': ['l4', '-', '2', '3'],
           'eps': ['l5', 'mm', '0.1', '0.2'],
           'Header': ['LLL', 'Min', 'Max'],
           'P': ['l6', 'MPa', '3', '5'],
           'T': ['l7', '°C', '30', '50'],
           'V': ['l8', 'm/s', '3', '5'],
           'nos': ['l10', '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 isinteger(value):
    """The function checks if an element is a number"""
    try:
        int(value)
        return True
    except ValueError:
        return False

def isnumber(value):
    return isfloat(value) or isinteger(value)

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

def allareinteger(var_list):
    """The function checks if all the elements in the lists are numbers"""
    check = True
    for item in var_list:
        check = check and isinteger(item)
    return check

def areallnumbers(var_list):
    check = True
    for item in var_list:
        check = check and (isfloat(item) or isinteger(item))
    return check

class DictionaryEntry(tk.Frame):
    """get entry and update dictionary values"""

    def __init__(self, parent, key_dict, values_dict, row_entry, bg=None, **kwargs):
        if bg is None:
            bg = parent['bg']
        super().__init__(parent, bg=bg, **kwargs)

        self.row = row_entry
        self.key = key_dict
        self.values = values_dict
        self.nac = tk.IntVar()
        self.entry_c1 = None
        self.entry_c2 = None

        if isnumber(self.values[-1]):
            if isnumber(self.values[-2]):

                self.variable = tk.StringVar(value=self.values[-2]), tk.StringVar(self, self.values[-1])

                tk.Checkbutton(parent, variable=self.nac, command=lambda: self.naccheck()).grid(row=self.row, column=0,
                                                                                                sticky='ns')

                label = self.values[0] + ' (' + self.values[1] + ') '
                tk.Label(parent, text=label, padx=10, pady=5).grid(row=self.row, column=1, sticky='nw')

                self.entry_c1 = tk.Entry(parent, textvariable=self.variable[0], width=10, state='normal')
                self.entry_c1.grid(row=self.row, column=2)

                self.entry_c2 = tk.Entry(parent, textvariable=self.variable[1], width=10, state='disabled')
                self.entry_c2.grid(row=self.row, column=3)

            else:
                self.variable = tk.StringVar(self, value=self.values[-1])

                tk.Label(parent, text='SIMULATION PARAMETERS', padx=10, pady=5).grid(row=self.row, columnspan=4,
                                                                                     sticky='ns')
                tk.Label(parent, text=self.values[0], padx=10, pady=5).grid(row=self.row + 1, columnspan=2, sticky='ns')
                self.variable = tk.StringVar(self, self.values[-1])
                self.entry_c1 = tk.Entry(parent, textvariable=self.variable, width=10, state='normal')
                self.entry_c1.grid(row=self.row + 1, column=2, columnspan=2)

            self.entry_c1.bind("<Key>", self._accept)
            if self.entry_c2 is not None:
                self.entry_c2.bind("<Key>", self._accept)

        else:
            tk.Label(parent, text=self.values[0], padx=10, pady=5).grid(row=self.row, column=1, sticky='ns')
            tk.Label(parent, text=self.values[1], padx=10, pady=5).grid(row=self.row, column=2, sticky='ns')
            tk.Label(parent, text=self.values[2], padx=10, pady=5).grid(row=self.row, column=3, sticky='ns')

        print(self.entry_c1, self.entry_c2)

    def naccheck(self):
        if self.nac.get() == 0:
            self.entry_c2.configure(state='disabled')
        else:
            self.entry_c2.configure(state='normal')

    def _accept(self, event):  # finire!! update dictionary
        """Accept value change when return is pressed or losing focus"""
        try:
            if self.entry_c1 is not None:
                self.values[-2] = self.entry_c1.get()
            if self.entry_c2 is not None:
                self.values[-1] = self.entry_c2.get()

        except ValueError:
            pass

if __name__ == '__main__':

    dictionary = create_input_dictionary()

    root = tk.Tk()
    radio_button_frame = tk.Frame(root, padx=10, pady=5)
    input_data_frame = tk.Frame(root, padx=10, pady=5)
    simul_button_frame = tk.Frame(root, padx=10, pady=5)

    # place the container within the main window using grid
    radio_button_frame.grid(row=0, column=0, sticky='ns')
    input_data_frame.grid(row=1, column=0, sticky='ns')
    simul_button_frame.grid(row=2, column=0, sticky='ns')

    row = 0
    for key, values in dictionary.items():
        obj = DictionaryEntry(input_data_frame, key, values, row)
        dictionary.update({key: obj.values})
        row += 1
    tk.Button(simul_button_frame, text="click me", command=lambda: print(dictionary)).pack(padx=10, pady=5)

    root.update()
    root.mainloop()

编辑:第一个点标记为固定

【问题讨论】:

  • 对于第一项,绑定&lt;KeyRelease&gt; 而不是&lt;Key&gt;
  • @acw1668 谢谢!
  • 这似乎比重现所询问的问题所需的代码要多得多。您能否尝试将代码缩减为minimal reproducible example
  • 对于第2项,如果您想在关联复选框未选中的情况下将entry_c1的内容复制到entry_c2,只需在禁用naccheck()之前在naccheck()内进行。
  • @acw1668 if self.nac.get() == 0: self.entry_c2.insert(0, self.values[-2])?

标签: python dictionary tkinter tkinter-entry


【解决方案1】:

对于第 1 项,只需绑定 &lt;KeyRelease&gt; 而不是 &lt;Key&gt;

对于第 2 项,只需将内容从 entry_c1 复制到 entry_c2,然后在 naccheck() 中禁用 entry_c2

    def naccheck(self):
        if self.nac.get() == 0:
            # copy value from entry_c1 to entry_c2
            value = self.variable[0].get()
            self.variable[1].set(value)
            # update self.values[-1] as well
            self.values[-1] = value
            # then disable entry_c2
            self.entry_c2.configure(state='disabled')
        else:
            self.entry_c2.configure(state='normal')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    相关资源
    最近更新 更多