tkinter create labels and entrys dynamically - python

I want to create a simple GUI where I can enter some values. A label before and at the and an button to start the script.
I was using something like this:
w = Label(master, text="weight:")
w.grid(sticky=E)
w = Label(root, text="bodyfathydrationmuscle:bones")
w.grid(sticky=E)
w = Label(root, text="hydration:")
w.grid(sticky=E)
its ok but i want to do it dynamic. also when i would use w for all the entrys i only could cast w.get once. but i need all my data ;-)
i was thinking of:
def create_widgets(self):
L=["weight","bodyfat","hydration","muscle","bones"]
LV=[]
for index in range(len(L)):
print(index)
print(L[index])
("Entry"+L[index])= Entry(root)
("Entry"+L[index]).grid(sticky=E)
("Label"+L[index])=Label(root, text=L[index])
("Label"+L[index]).grid(row=index, column=1)
To call later:
var_weight=Entryweight.get()
var_bodyfat=Entrybodyfat.get()
and so on. how can i make it work?

Your program suggests that Entrybodyfat and the other variables should be generated on the fly, but you don't want to do that.
The normal approach is to store the entries and labels in a list or a map:
from Tkinter import *
root = Tk()
names = ["weight", "bodyfat", "hydration", "muscle", "bones"]
entry = {}
label = {}
i = 0
for name in names:
e = Entry(root)
e.grid(sticky=E)
entry[name] = e
lb = Label(root, text=name)
lb.grid(row=i, column=1)
label[name] = lb
i += 1
def print_all_entries():
for name in names:
print entry[name].get()
b = Button(root, text="Print all", command=print_all_entries)
b.grid(sticky=S)
mainloop()
The value of the bodyfat entry is then entry["bodyfat"].get().

Related

How do I pass variables from tkinter forms to different functions?

I'm trying to make an example for some high school students using tkinter with multiple forms, and accessing form data in different functions. I'm trying to keep the example simple, but having a small problem. The sv3 & sv4 variables are not getting the values from the second form. Any suggestions or ideas?
from tkinter import *
root = Tk()
sv1 = StringVar()
sv2 = StringVar()
sv3 = StringVar()
sv4 = StringVar()
#first function - this DOES NOT take text from entry widgets and displays, but should
def callback2():
test2 = sv3.get()
print(test2)
print (sv4.get())
print("show second form entry widgets values")
return True
#first function - this takes text from entry widgets and displays
def callback():
test = sv1.get()
print(test)
print (sv2.get())
print("show first form entry widgets values")
new_form()
return True
#new form
def new_form():
newfrm = Tk()
entry3 = Entry(newfrm, textvariable=sv3).pack()
entry4 = Entry(newfrm, textvariable=sv4).pack()
button = Button(newfrm, text="Click Me", command=callback2).pack()
newfrm.mainloop()
#initial form
def main_form():
entry1 = Entry(root, textvariable=sv1).pack()
entry2 = Entry(root, textvariable=sv2).pack()
button = Button(root, text="Click Me", command=callback).pack()
root.mainloop()
main_form()
Here how to avoid using multiple Tk instances and manually transfers the values from the first two Entrys to the second pair. See lines with #### comments.
from tkinter import *
root = Tk()
sv1 = StringVar()
sv2 = StringVar()
sv3 = StringVar()
sv4 = StringVar()
#first function - this now take text from entry widgets and displays as it should.
def callback2():
test2 = sv3.get()
print(test2)
print (sv4.get())
print("show second form entry widgets values")
return True
#first function - this takes text from entry widgets and displays
def callback():
test = sv1.get()
print(test)
print (sv2.get())
print("show first form entry widgets values")
new_form()
return True
#new form
def new_form():
#### newfrm = Tk()
newfrm = Toplevel() #### Instead.
sv3.set(sv1.get()) #### Trasfer value.
sv4.set(sv2.get()) #### Trasfer value.
entry3 = Entry(newfrm, textvariable=sv3).pack()
entry4 = Entry(newfrm, textvariable=sv4).pack()
button = Button(newfrm, text="Click Me", command=callback2).pack()
newfrm.mainloop()
#initial form
def main_form():
entry1 = Entry(root, textvariable=sv1).pack()
entry2 = Entry(root, textvariable=sv2).pack()
button = Button(root, text="Click Me", command=callback).pack()
root.mainloop()
main_form()

Retrieving Data from Tkinter Window

I created this tkinter window and created these drop down boxes.
while number != (max+1):
Subject1_Label = Label(master, text=("Subject", number))
Subject1_Label.grid(row=number, column=0, pady=6)
Subject1 = All_Subjects.get(number)
variable = StringVar(master)
variable.set(Subject1[0])
w = OptionMenu(master, variable, *Subject1)
w.grid(row=number, column=1, pady=6)
subject_amount = subject_amount + 1
number = number + 1
Usually to determine the input from the dropdown boxes I could simply use (variable.get) but in this case variable is being used 5 times to create 5 different boxes. Is there a way I can gather the input from these dropdown boxes using their position on the tkinter window. Such as (variable.get, row=1, column=1)? Or any other way?
You can use list or dictionary to store the variables. Below is an example using dictionary:
variables = {}
while number != (max+1):
subject = f"Subject {number}"
Subject1_Label = Label(master, text=subject)
Subject1_Label.grid(row=number, column=0, pady=6)
Subject1 = All_Subjects.get(number)
variable = StringVar(master)
variable.set(Subject1[0])
variables[subject] = variable # save the variable
w = OptionMenu(master, variable, *Subject1)
w.grid(row=number, column=1, pady=6)
subject_amount = subject_amount + 1
number = number + 1
Then you can use something like variables["Subject 1"].get() to get the selected item of "Subject 1".
Update with an example:
from tkinter import *
# just for providing "All_Subjects.get(number)" in the while loop
class All_Subjects:
subjects = ("math stand", "english standard", "chem", "timber", "child studies")
def get(n):
return All_Subjects.subjects
master = Tk()
max = 5
variables = {}
number = 1
subject_amount = 0
while number != (max+1):
subject = f"Subject {number}"
Subject1_Label = Label(master, text=subject)
Subject1_Label.grid(row=number, column=0, pady=6)
Subject1 = All_Subjects.get(number)
variable = StringVar(master)
variable.set(Subject1[0])
variables[subject] = variable # save the variable
w = OptionMenu(master, variable, *Subject1)
w.grid(row=number, column=1, pady=6)
subject_amount = subject_amount + 1
number = number + 1
def show_subjects():
# use "Subject X" as key to get the selected subjects
for i in range(1, max+1):
subject = f"Subject {i}"
print(f"{subject}: {variables[subject].get()}")
# or simply
#print([var.get() for var in variables.values()])
Button(master, text="Next", command=show_subjects).grid(column=2, padx=10, pady=10)
master.mainloop()
Output:

Adding elements using Tkinter Dynamically

I am trying to create the program that has an add button, When it is clicked, several different elements like entries and buttons should appear on the output window. Firstly I am not able to structure the display correctly and secondly I am not sure as to how to get the values entered by the user in entry widget of Tkinter.
Here is the Code:
from tkinter import *
from tkinter import messagebox
lb = Tk()
def addentry():
i = 3 // the 3 here should keep on incrementing so that the row goes on increasing as the user
keeps on adding different entries. This is for the display
ent1 = Entry(lb, bd=5).grid(row =i ,column= 0)
ent2 = Entry(lb, bd=5).grid(row = i, column=2)
ent3 = Entry(lb, bd=5).grid(row = i, column=4)
ent4 = Entry(lb, bd=5).grid(row = i , column=6)
addent = Button(lb, text = "Add Entry",command = addentry).grid(row = 0, column = 2)
It's all about keepin references. References are used to identify objects.
import tkinter as tk
root = tk.Tk()
my_entries = []
entry_row = 1
def addentry():
global entry_row
ent = tk.Entry(root, bd=5)
ent.grid(row =entry_row ,column= 0)
my_entries.append(ent)
entry_row = entry_row+1
def getter():
for entry in my_entries:
my_stuff = entry.get()
print(my_stuff)
addent = tk.Button(root, text = "Add Entry",command = addentry)
addent.grid(row = 0, column = 0)
getent = tk.Button(root,text='get input', command= getter)
getent.grid(row=0, column=1)
root.mainloop()
In this exampel we keepin the references of the tk.Entry and the variable entry_row while we would like to work with later on. There are a bunch of solution for this. Here we had used a global variable and a list in the global namespace to access them.

Python entry to store input into a variable stores nothing, returns initial value

Ok, so basic story. I have created an entry. After you introduce text, you have to click a button to store the inputted text into a variable that is later printed.
Here is the code:
from Tkinter import *
def myClick(entry_name, var):#defines function to get input from entry and store into var
var = entry_name.get()
root = Tk()#creates initial tk
lbl1 = Label(root, text = "hello")#before entry label
lbl1.grid(row = 0, column = 0)#label griding
ent = Entry(root, width = 15)# the entry
ent.grid(row = 1, column = 0)#entry gridding
hello = None #variable to store entry input
bt1 = Button(root, command = myClick(ent, hello))#button 1 creation and function attribution
bt1.grid(row = 3, column = 0)#button 1 griding
root.mainloop()
print(hello)
It is very unclear to me why the function does not get the input from the entry.
bt1 = Button(root, command = myClick(ent, hello))
In this line, you call myClick function with parameters, not just pass it. That means that myClick is executed once after the module is launched and then it does nothing. If you want to print the entry input, I recommend you do the following:
from tkinter import *
root = Tk()
lbl1 = Label(root, text="hello")
lbl1.grid(row=0, column=0)
ent = Entry(root, width=15)
ent.grid(row=1, column=0)
def myClick():
var = ent.get()
print(var)
bt1 = Button(root, command=myClick)
bt1.grid(row=3, column=0)
root.mainloop()
Also code after root.mainloop() doesn't excecute.
just define a normal function :
from tkinter import *
def blinta():
var = ent.get()
ent.delete(0,END)
print(var)
root = Tk()#creates initial tk
lbl1 = Label(root, text = "hello")#before entry label
lbl1.grid(row = 0, column = 0)#label griding
ent = Entry(root, width = 15)# the entry
ent.grid(row = 1, column = 0)#entry gridding
bt1 = Button(root, command = blinta)
bt1.grid(row = 3, column = 0)
root.mainloop()
This will work I'm sure.

Print Values from a Sequence of Entries / ComboBoxes

I want to build a program to add a basketball lineup.
Ideally I want the output to be (as an example):
Center, John
Point Guard, Jack
Shooting Guard, James
This would depend on how many values you add and what you type for the name. I am struggling to pull these values that are entered. I am not getting an error - just not getting the results I am looking for. For example, instead of "Point Guard", it says "". I am also not returning a value for the Entry fields. Any help would be greatly appreciated!!
'''
import tkinter as tk
from tkinter import *
from tkinter import ttk
root = Tk()
menu = Menu(root)
root.config(menu=menu)
combovalues = ['Center' , 'Point Guard' , 'Shooting Guard' , 'Power Forward' , 'Small Forward' ]
startinglineup = []
entry_values = []
root.counter = 2
my_lineup = []
string_var = tk.StringVar()
entry_values.append(string_var)
def addlineup():
Label(root, text='Lineup Name').grid(row=0)
e1 = Entry(root)
e1.grid(row=0, column=1)
combobox = ttk.Combobox(root, values=combovalues)
combobox.grid(column=0, row=1)
e2 = Entry(root)
e2.grid(row=1, column=1)
addbutton = tk.Button(root, text='Add', width=25, command=add)
addbutton.grid(column=0, row=14)
confirmbutton = tk.Button(root, text='Confirm', width=25, command=save)
confirmbutton.grid(column=0, row=15)
def save():
number = root.counter
print(my_lineup)
def add():
root.counter += 1
combobox = ttk.Combobox(root, values=combovalues)
combobox.grid(column=0, row=root.counter)
entry = Entry(root)
entry.grid(row=root.counter, column=1)
for stringvar in entry_values:
text = string_var.get()
if text:
my_lineup.append(text)
my_lineup.append([text, combobox])
# --- main menu ---
filemenu = Menu(menu)
menu.add_cascade(label='File', menu=filemenu)
# --- lineups ----
lineupmenu = Menu(menu)
menu.add_cascade(label='Lineups', menu=lineupmenu)
lineupmenu.add_command(label='Add Lineup', command=addlineup)
lineupmenu.add_command(label='View Lineups')
mainloop()
'''
To get results from an entry:
Create a StringVar() (If you want to store the result in a different variable and not the Entry itself)
string_var = tk.StringVar()
Creat an Entry
entry = tk.Entry(root, textvariable=string_var)
entry.pack()
Remember to add string_var to the parameter textvariable, textvariable=string_var.
Finally, get the result (it can be done at any time)
result = string_var.get()
Or, you can just do (If you don't care to store the result in the Entry itself) :
entry = tk.Entry(root)
entry.pack()
result = entry.get()
You don't actually need a StringVar

Categories

Resources