基于tkinter的GUI,应该更新字典值。它工作得很好,但仍然有两个问题:
-
为了更新条目值,我使用了
bind
方法,即object.bind("<Key>", self._accept)
,它仅与Enter键一起工作,与其他键一起打印插入条目[SOLVED]中的先前值。 - 当相应的复选框停用时,我不知道如何设置
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()
编辑:第一个点标记为固定
对于第1项,只需绑定<KeyRelease>
而不是<Key>
。
对于第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')