MaxB
MaxB

Reputation: 458

Store variables entered in tkinter form

I am creating a Tkinter-based form where I want to store each item that the user types in as a separate variable. I understand how to generate the form, but I am lost on how to handle the program after the user presses the Enter button. I really just need everything stored as a string.

from tkinter import *
import pandas as pd

fields = ('Event', 'Event Folder', 'Session', 'Date: (MM/DD/YYYY)', 'StartTime: 24HR(HH:MM)', 'EndTime: 24HR(HH:MM)')

def saveVars(entries):
    locals().update(entries)
    return 

def makeform(root, fields):
   entries = {}
   for field in fields:
      row = Frame(root)
      lab = Label(row, width=22, text=field+": ", anchor='w')
      ent = Entry(row)
      ent.insert(0,"")
      row.pack(side = TOP, fill = X, padx = 5 , pady = 5)
      lab.pack(side = LEFT)
      ent.pack(side = RIGHT, expand = YES, fill = X)
      entries[field] = ent
   return entries

if __name__ == '__main__':
   root = Tk()
   ents = makeform(root, fields)
   b1 = Button(root, text = 'Enter', command = lambda e = ents: saveVars(e))
   b1.pack(side = LEFT, padx = 5, pady = 5)
   root.mainloop()

Upvotes: 1

Views: 310

Answers (2)

Mike - SMT
Mike - SMT

Reputation: 15236

What you need to do is build a function that does something with your entry fields. That said you may want to change up you code a little bit to make this easier. Instead of building your labels and entry fields in a function build them in the global namespace and then store the entry fields in a list.

import tkinter as tk

fields = ('Event', 'Event Folder', 'Session', 'Date: (MM/DD/YYYY)',
          'StartTime: 24HR(HH:MM)', 'EndTime: 24HR(HH:MM)')


def do_something_with_entries():
    for ndex, entry in enumerate(entry_list):
        print(fields[ndex], ': ', entry.get())


if __name__ == '__main__':
    root = tk.Tk()
    entry_list = []
    for field in fields:
        row = tk.Frame(root)
        lab = tk.Label(row, width=22, text=field + ": ", anchor='w')
        ent = tk.Entry(row)
        entry_list.append(ent)
        row.pack(side='top', fill='x', padx=5, pady=5)
        lab.pack(side='left')
        ent.pack(side='right', expand='yes', fill='x')

    tk.Button(root, text='Enter', command=do_something_with_entries).pack(side='left', padx=5, pady=5)
    root.mainloop()

Results:

enter image description here

Here is an example using pandas:

import tkinter as tk
import pandas as pd


fields = ['Event', 'Event Folder', 'Session', 'Date: (MM/DD/YYYY)', 'StartTime: 24HR(HH:MM)', 'EndTime: 24HR(HH:MM)']
df = pd.DataFrame(columns=fields)


def do_something_with_entries():
    global df
    stored_values = []
    for ndex, entry in enumerate(entry_list):
        stored_values.append(entry.get())

    series = pd.Series(stored_values, index=fields)
    df = df.append(series, ignore_index=True)


if __name__ == '__main__':
    root = tk.Tk()
    entry_list = []
    for field in fields:
        row = tk.Frame(root)
        lab = tk.Label(row, width=22, text=field + ": ", anchor='w')
        ent = tk.Entry(row)
        entry_list.append(ent)
        row.pack(side='top', fill='x', padx=5, pady=5)
        lab.pack(side='left')
        ent.pack(side='right', expand='yes', fill='x')

    tk.Button(root, text='Enter', command=do_something_with_entries).pack(side='left', padx=5, pady=5)
    root.mainloop()

Upvotes: 2

demian-wolf
demian-wolf

Reputation: 1858

You are storing the questions as keys and Entry widgets as values of the entries dict.

Firstly, put the entries dict out of the makeform function (otherwise, only makeform function would be able to use it)
Secondly, create the answer dict. We are going to store the answers here.
Thirdly, create a fetch function which is to be called when the user clicks Enter button. It will go through the entries dict and set the values of the answers dict to the entered answers (using Entry.get(...) method)
Now you can process the form answers.

Here is an example:

from tkinter import *
import pandas as pd



fields = ('Event', 'Event Folder', 'Session', 'Date: (MM/DD/YYYY)',
    'StartTime: 24HR(HH:MM)', 'EndTime: 24HR(HH:MM)')
entries = {}
answers = {}

def makeform(root, fields):
   for field in fields:
      row = Frame(root)
      lab = Label(row, width=22, text=field + ": ", anchor='w')
      ent = Entry(row)
      row.pack(side=TOP, fill=X, padx=5, pady=5)
      lab.pack(side=LEFT)
      ent.pack(side=RIGHT, expand=YES, fill=X)
      entries[field] = ent
   return entries

def fetch():
   for question in entries:
      answers[question] = entries[question].get()
   print(answers) # do something with the results now

if __name__ == '__main__':
   root = Tk()
   ents = makeform(root, fields)
   root.bind('<Return>', fetch)
   b1 = Button(root, text='Enter', command=fetch)
   b1.pack(side=LEFT, padx=5, pady=5)
   root.mainloop()

PS: You don't need to use a lambda-function as the button command. Simply use the fetch function as a command.
PS 1: And why do you call ent.insert(0, "")? It has no effect.

Upvotes: 0

Related Questions