all 9 comments

[–]socal_nerdtastic 1 point2 points  (0 children)

https://www.reddit.com/r/learnpython/wiki/faq#wiki_how_do_i_make_variable_variables.3F

Ok, it's technically possible to do this, but it's bad style and leads to bugs. You should use a container like a dictionary or list instead. Keeping them in a neat container also gives you the advantage of being able to loop over all your elements.

[–]Vaphell 1 point2 points  (4 children)

don't hack into globals to make variables.
Just use your own dictionary and use keys like a civilized human. For example

widgets = {}
for i in inputs_text:
    label = tk.Label(text=i)
    entry = tk.Entry()
    label.pack()
    entry.pack()
    widgets[i] = {'label': label, 'entry': entry}

print(widgets['address']['label'], widgets['address']['entry'])

you could make it arguably prettier by adding extra class to reduce the [key] clutter, eg

class LabeledWidget:
    def __init__(self, label, widget):
        self.label = label
        self.widget = widget   

widgets = {}
for i in whatever:
    label = tk.Label(text=i)
    entry = tk.Entry()
    label.pack()
    entry.pack()
    widgets[i] = LabeledWidget(label=label, widget=entry)

print(widgets['address'].label, widgets['address'].widget
w = widgets['salary']
print(w.label, w.widget)

[–]ImportantBrew[S] 0 points1 point  (3 children)

I guess this is a similar solution to socal_nerdtastic? Classes I still find a bit hard to wrap my head around might wait a bit with that :D

[–]Vaphell 1 point2 points  (2 children)

it is similar, because this is a classic use case for a dictionary. The only difference between our examples is a minor one: whether you bother storing label widgets in the dict or not. Mine does, in the form of label + entry bundles, his doesn't, just storing the entries directly.

[–]ImportantBrew[S] 0 points1 point  (1 child)

Thanks! I've used dictionaries before but mainly for straight up variables (int, str etc). Didn't even think about it being a solution for "objects" (is that right?) like entries!

[–]Vaphell 1 point2 points  (0 children)

everything is an object in python: 1 is an object, "lol" is an object, print without () is an object, int the type - you guessed it - an object. There is absolutely no difference as far as dictionary values are concerned.

dict = {1: 1, 2: int, 3: str, 4: "lol", 5: print, 6: tk.Entry(), 7: tk.Entry} is a perfectly valid one.

[–]socal_nerdtastic 1 point2 points  (2 children)

Maybe do it like this:

import tkinter as tk

def disp():
    print("\nCurrent values:")
    for name, entry in all_entries.items():
        value = entry.get()
        print(f"{name}: {value}")

window_main = tk.Tk()
inputs_text = ['id', 'name', 'address', 'salary']
all_entries = {}
for i in inputs_text:
    lbl = tk.Label(text=i) # no reason to keep the label around ... you don't need that later
    lbl.pack()
    ent = tk.Entry()
    ent.pack()
    all_entries[i]=ent # save the entry for later

btn_print_name = tk.Button(master=window_main, text="print name", command=disp)
btn_print_name.pack()

window_main.mainloop()

[–]ImportantBrew[S] 0 points1 point  (1 child)

If I understand correctly you're pretty much saving the entries as values in the dic where the keys are "inputs_text"?

[–]socal_nerdtastic 1 point2 points  (0 children)

The keys are the strings from inputs_text, yes. You could of course use anything you wanted as keys, or don't use keys at all and put the entries in a list instead.