Last active
September 17, 2022 10:38
-
-
Save silvio2402/aee8dd9de13cf2cd7fe0b1c7ef13c33d to your computer and use it in GitHub Desktop.
EditableList for tkinter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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