0

I want to create a form and read it's contents later currently I am thinking of writing something like this:

import tkinter as tk
objectkeylist=["name","lastname","age"]
root = tk.Tk()
textwidgetdict=dict()
textwidgetdict("name") =tk.Text(root, height=3, width=50)
textwidgetdict("lastname")=tk.Text(root, height=3, width=50)
textwidgetdict("age")=tk.Text(root, height=3, width=50)

textwidgetdict("name").pack()
textwidgetdict("lastname").pack()
textwidgetdict("age").pack()

def getcontent():
  formcontentdict=dict()
  formcontentdict("name") =textwidgetdict("name").get("1.0", tk.END)
  formcontentdict("lastname") =textwidgetdict("lastname").get("1.0", tk.END)
  formcontentdict("age") =textwidgetdict("age").get("1.0", tk.END)
  return formcontentdict()


tk.mainloop()

Can I somehow reduce the redundant code with something like

map(lambda : objectlist[index]_text=objectlist.get("1.0", tk.END) , objectlist)

or

for object in objectlist:
    object_text=objectlist.get("1.0", tk.END)

?

I don't even know what the correct keyword is to search for this.

I understand that the better idea ist to use the items of objectlist as keys for a dictionary like explained here: https://stackoverflow.com/a/4010869/3503111 I hope this code is more clear on what I want to achieve though

Nivatius
  • 260
  • 1
  • 13
  • The desire to use a datastructure on one side, but then insist on a hard-coded variable on the other side is a contradiction. Either store both in a data-structure that is appropriate (e.g. an ordered dict) or hard-code. You can of course reduce boilerplate by introducing utility functions to create widgets and obtain the data. – deets Jul 03 '19 at 10:54
  • thank you, I updated my code accordingly – Nivatius Jul 03 '19 at 11:21

2 Answers2

2

Why do you need to establish those names dynamically? Do you plan to access them using dynamic references as well? The preferred way to handle such situations is to use a container object such as a list or a dictionary to hold the objects.

Your second snippet was almost right. It's perfectly normal and acceptable to write

text_list = []
for object in objectlist:
    object_text = object.get("1.0", tk.END)
    text_list.append(object_text)

You have probably already noticed that you can't create a list containing word, otherword and more_word until you have assigned values to those variables, so that statement needs to occur later in the program.

holdenweb
  • 33,305
  • 7
  • 57
  • 77
1

I'm not sure what your objectlist is meant to contain because its contents are not defined until after, and if they were defined, you immediately overwrite them anyway.

The fact that there are separate variable names seems to have little relevance, but perhaps this is a simplification that would be helpful.

If you have a list of names of components:

component_names = ['word', 'otherword', 'moreword']

And a function which creates a new component, packs it, and returns a function which gets the text:

def create_pack_text(root):
    comp = tk.Text(root, height=3, width=50)
    comp.pack()
    # return comp.get('1.0', tk.END)
    return lambda: comp.get('1.0', tk.END)

You could get a dict mapping names to text parts like this:

root = tk.Tk()
mapping = { name: create_pack_text(root) for name in component_names }

tk.mainlook()

# edit
mapping['word'] # a function which returns the contents of the component
print(mapping['word']())

EDIT You could make create_pack_text return a tuple of the text component and the lambda expression. Then

comp, fun = mapping['word']
# comp is the actual component
# fun() gets the text in it
blueteeth
  • 3,330
  • 1
  • 13
  • 23
  • you correctly assumed that my list was supposed to contain component names. Of course I don't want to get the content right away(it will be empty), but at a button press. – Nivatius Jul 03 '19 at 11:09
  • @Nivatius I've edited `create_pack_text` to return a function. Also described how you could maintain access to both the component and the function. – blueteeth Jul 03 '19 at 11:33