0

I have created a simple gui that displays a variable amount of floats from a given list as label widgets in one column and then a corresponding amount of entry boxes in the adjacent column. I am able to "get" the value of the last entry widget with no problem. However, I would like to "get" the values of all of the entry widgets. Ideally this would be a dictionary, but I'll take any output at this point. I have looked at Is there anyway to get all the values of a Entry Widget that I put in a for loop?; Create variable number of Entry widgets with names from list; Tkinter get the text from entry boxes; Variable Number of Entry Fields in Tkinter; Get values from Entry widgets and create list of variables Tkinter; and many, many more, but none of these have really given a straight-forward answer or at least one that I can apply.

The amount of label/entry widgets can range from 1 to probably 15 with no way of knowing beforehand. Below is my code snippet.

import sys
import tkinter as tk
from tkinter import ttk

def share_cost_basis(fund, pool, price):
    def get_px(*args):
        # This is the issue part
        for p in price:
            my_px = float(p) * float(entry.get())
            print(my_px)
        # End issue part
        form.destroy()
        sys.exit(0)
    form = tk.Tk()
    form.update_idletasks()
    width = 400
    height = 450
    x = int((form.winfo_screenwidth() / 2) - (width / 2))
    y = int((form.winfo_screenheight() / 2) - (height / 2))
    form.geometry('{}x{}+{}+{}'.format(width, height, x, y))
    form.title('Cost Basis per Share Entry')
    form_label = ttk.Label(form, text=f'For the fund {pool} {fund}, please enter the number of\n'
                                      f' shares that were purchased at each price.\n')
    form_label.grid(column=1, row=1, columnspan=4, sticky='E,W', pady=(20, 0), padx=(10, 0))
    px = tk.StringVar()
    for p in price:
        px.set(p)
        label_frame = ttk.LabelFrame(form, borderwidth=10, relief='sunken')
        row_num = price.index(p) + 2
        label_frame.grid(row=row_num, column=1, pady=5, sticky='e', columnspan=2)
        label = ttk.Label(label_frame, text=p)
        label.grid(row=row_num, column=1, columnspan=2)
        entry = ttk.Entry(form)
        entry.grid(row=row_num, column=3)
    ok_button = ttk.Button(form, text='OK', command=get_px)
    ok_button.grid(row=row_num+2, column=2)
    form.mainloop()

share_cost_basis('Test Fund', 'Test Pool', ['1.25', '2.50', '3.75', '5.00'])

Any and all help is appreciated.

Thanks!!

AJames
  • 81
  • 1
  • 1
  • 10
  • 1
    Thats because you keep assigning the new entry boxes in the loop to the same variable and thus the last one is the only one you can get values from. To fix this make a list that you then insert each entry into in order to keep a good easy to find reference for each entry. – Mike - SMT Jan 03 '23 at 15:35
  • 1
    All of the questions you mentioned to address the problem with the same basic solution: store the entry widgets in a list or dictionary, then iterate over the list or dictionary to get the values. – Bryan Oakley Jan 03 '23 at 15:37

1 Answers1

2

So the solution in this case for me would be to use a list to hold the entry fields and then check values based on index.

here is an example with your code modified to use a list.

import sys
import tkinter as tk
from tkinter import ttk


def share_cost_basis(fund, pool, price):
    def get_px(*args):
        for ndex, p in enumerate(price):
            # based on the index of your price list we also pull the value from the entry list
            my_px = float(p) * float(list_of_entry_fields[ndex].get())
            print(my_px)
        form.destroy()
        sys.exit(0)

    form = tk.Tk()
    form.update_idletasks()
    list_of_entry_fields = []  # Added a list to store entry fields
    width = 400
    height = 450
    x = int((form.winfo_screenwidth() / 2) - (width / 2))
    y = int((form.winfo_screenheight() / 2) - (height / 2))
    form.geometry('{}x{}+{}+{}'.format(width, height, x, y))
    form.title('Cost Basis per Share Entry')
    form_label = ttk.Label(form, text=f'For the fund {pool} {fund}, please enter the number of\n'
                                      f' shares that were purchased at each price.\n')
    form_label.grid(column=1, row=1, columnspan=4, sticky='E,W', pady=(20, 0), padx=(10, 0))
    px = tk.StringVar()
    for p in price:
        px.set(p)
        label_frame = ttk.LabelFrame(form, borderwidth=10, relief='sunken')
        row_num = price.index(p) + 2
        label_frame.grid(row=row_num, column=1, pady=5, sticky='e', columnspan=2)
        label = ttk.Label(label_frame, text=p)
        label.grid(row=row_num, column=1, columnspan=2)
        # appending list of entry fields with each one in the loop
        list_of_entry_fields.append(ttk.Entry(form))
        # after appending we can use -1 to reference the last item appened
        list_of_entry_fields[-1].grid(row=row_num, column=3)
    ok_button = ttk.Button(form, text='OK', command=get_px)
    ok_button.grid(row=row_num+2, column=2)
    form.mainloop()

share_cost_basis('Test Fund', 'Test Pool', ['1.25', '2.50', '3.75', '5.00'])

Result:

enter image description here

Values printed to Console:

2.5
7.5
15.0
25.0
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79