Skip to content

Instantly share code, notes, and snippets.

@silvio2402
Last active September 17, 2022 10:38
Show Gist options
  • Save silvio2402/aee8dd9de13cf2cd7fe0b1c7ef13c33d to your computer and use it in GitHub Desktop.
Save silvio2402/aee8dd9de13cf2cd7fe0b1c7ef13c33d to your computer and use it in GitHub Desktop.
EditableList for tkinter
from tkinter import *
# zip values until all arguments are exhausted
def zip_nostop(*iterables):
lists = [list(iterable) for iterable in iterables]
lens = [len(l) for l in lists]
for i in range(max(lens)):
tup: list = []
for iterable in iterables:
try:
val = list(iterable)[i]
except IndexError:
val = None
tup.append(val)
yield tuple(tup)
class EditableList(Frame):
def __init__(self, parent, str_list=[], **kwargs):
Frame.__init__(self, parent, **kwargs)
self._text_vars: list[StringVar] = []
self._entries: list[Entry] = []
self.columnconfigure(0, weight=1)
self.items = str_list
@property
def items(self):
items = []
for text_var in self._text_vars:
val = text_var.get()
if val != "":
items.append()
return items
@items.setter
def items(self, values: list[str]):
new_entries = []
new_text_vars = []
for new_value, entry_var in zip_nostop([*values, ""], zip(self._entries, self._text_vars, strict=True)):
if new_value != None and entry_var != None:
entry, text_var = entry_var
if text_var.get() != new_value:
text_var.set(new_value)
new_entries.append(entry)
new_text_vars.append(text_var)
elif new_value == None and entry_var != None:
entry, text_var = entry_var
entry.destroy()
elif new_value != None and entry_var == None:
new_text_var = StringVar()
new_entry = Entry(self, textvariable=new_text_var)
new_entry.grid(row=len(new_entries), sticky='we')
new_entry.bind("<KeyRelease>", self.bind_key_released)
new_text_var.set(new_value)
new_entries.append(new_entry)
new_text_vars.append(new_text_var)
else:
print()
self._entries = new_entries
self._text_vars = new_text_vars
def bind_key_released(self, _):
self.update_fields()
def update_fields(self):
new_entries = []
new_text_vars = []
new_i = 0
for entry, text_var in zip(self._entries, self._text_vars, strict=True):
val = text_var.get()
last = entry == self._entries[-1]
if val == "" and not last:
entry.destroy()
else:
entry.grid(row=new_i, sticky='we')
new_i += 1
new_text_vars.append(text_var)
new_entries.append(entry)
if not new_text_vars or new_text_vars[-1].get() != "":
new_text_var = StringVar()
new_entry = Entry(self, textvariable=new_text_var)
new_entry.bind("<KeyRelease>", self.bind_key_released)
new_entry.grid(row=len(new_entries), sticky='we')
new_text_vars.append(new_text_var)
new_entries.append(new_entry)
self._text_vars = new_text_vars
self._entries = new_entries
return True
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment