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

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()

Related

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

How to get output from class after input all values

from tkinter import *
app = Tk()
app.title("First Software")
app.minsize(500, 500)
#For Input Declaration
UserName = StringVar()
pass1 = IntVar()
class Functions:
def username(self, UserName):
self.UserName = Username
print(UserName.get())
def password(self, pass1):
self.pass1 = pass1
print(pass1.get())
#---Label---
label = Label(text='Enter any Number between 1 and 100...').pack()
#---Entry---
entry = Entry(app, textvariable=UserName).pack()
entry1 = Entry(app, textvariable=pass1).pack()
#---Buttton---
button = Button(text='Submit', command=Functions).pack()
app.mainloop()
After running this code, How can I get separate input of Username and password by using this method. I'm lil bit confused right now!
command=Functions tells Tkinter to create an instance of your Functions class when the Submit button is pressed. But it doesn't tell it to call the functions defined inside Functions. However, that class definition is a bit odd, and you don't really need a class to contain those functions. Instead, we can write a simple function that gets the values of UserName and pass1 and prints them.
I've made a few other minor changes to your code.
import tkinter as tk
app = tk.Tk()
app.title("First Software")
#app.minsize(500, 500)
#For Input Declaration
UserName = tk.StringVar()
pass1 = tk.IntVar()
def print_entries():
print('User name:', UserName.get())
print('Password:', pass1.get())
tk.Label(app, text='User name.').pack()
entry = tk.Entry(app, textvariable=UserName)
entry.pack()
tk.Label(app, text='Password\nEnter any Number between 1 and 100').pack()
entry1 = tk.Entry(app, textvariable=pass1)
entry1.pack()
tk.Button(app, text='Submit', command=print_entries).pack()
app.mainloop()
This code doesn't actually need the names entry and entry1, but I kept them in case you want to add code that does need to refer to those widgets by name.
Note that you should not do
entry = Entry(app, textvariable=UserName).pack()
The .pack method returns None, so the above statement assigns the value of None to entry. Instead, we do
entry = tk.Entry(app, textvariable=UserName)
entry.pack()
That assigns the new Entry widget to the name entry and then calls its .pack method to pack it into the window.
If you like, you can wrap that code up in a class, but I wouldn't bother with a simple GUI like this. But this is one way to do it:
import tkinter as tk
class App:
def __init__(self):
root = tk.Tk()
root.title("First Software")
#root.minsize(500, 500)
#For Input Declaration
self.UserName = tk.StringVar()
self.pass1 = tk.IntVar()
tk.Label(root, text='User name.').pack()
entry = tk.Entry(root, textvariable=self.UserName)
entry.pack()
tk.Label(root, text='Password\nEnter any Number between 1 and 100').pack()
entry1 = tk.Entry(root, textvariable=self.pass1)
entry1.pack()
tk.Button(root, text='Submit', command=self.print_entries).pack()
root.mainloop()
def print_entries(self):
print('User name:', self.UserName.get())
print('Password:', self.pass1.get())
App()

Trying to change label using entry box and button

I'm trying to make a label that will change when I enter text into the entry box and click the button.
I've tried doing some research but can't seem to find out how to do it .
from tkinter import *
master = Tk()
master.title("Part 3")
v = StringVar()
v.set("Please change me")
lb= Label(master, textvariable=v, fg="red",bg="black").grid(row=0,column=0)
ent= Entry(master, textvariable=v,).grid(row=1,column=2)
b1= Button(master, text="Click to change", fg="red",bg="black").grid(row=1,column=0)
to do so, you first need to define a callback that changes the value. (example below)
You should also use two Variables of type StringVar to store the different Values
from tkinter import *
master = Tk()
master.title("Part 3")
lText = StringVar()
lText.set("Please change me")
eText = StringVar()
def ChangeLabelText(event=None):
global lText
global eText
lText.set(eText.get())
Then, bind the callback to the button
lb = Label(master, textvariable=lText, fg="red",bg="black").grid(row=0,column=0)
ent = Entry(master, textvariable=eText).grid(row=1,column=2)
b1 = Button(master, text="Click to change", fg="red",bg="black", command=ChangeLabelText).grid(row=1,column=0)

Creating new entry boxes with button Tkinter

How do i make the button to add two box (side by side) below when it is being clicked as the user decided to put more input?
def addBox():
labelframe = Tkinter.Frame()
labelframe.bind("<Add Input>", callback)
labelframe.pack()
labelframe = Tkinter.Frame()
labelFrom = Tkinter.Label(labelframe, text= "from")
labelFrom.grid(column=1, row=0)
e = Tkinter.Entry(labelframe)
e.grid(column=1, row=1)
labelTo = Tkinter.Label(labelframe, text= "to")
labelTo.grid(column=2, row=0)
e2 = Tkinter.Entry(labelframe)
e2.grid(column=2, row=1)
labelframe.pack()
addboxButton = Button( root,text='<Add Time Input>', fg="Red",command="addBox")
addboxButton.pack(side=Tkinter.TOP)
This is example how to add Entry.
Probably you get problem because you use quotation marks in command=addBox
Because you will have to get values from entries you have to remeber them on list.
I add button which print text from entries.
from Tkinter import *
#------------------------------------
def addBox():
print "ADD"
ent = Entry(root)
ent.pack()
all_entries.append( ent )
#------------------------------------
def showEntries():
for number, ent in enumerate(all_entries):
print number, ent.get()
#------------------------------------
all_entries = []
root = Tk()
showButton = Button(root, text='Show all text', command=showEntries)
showButton.pack()
addboxButton = Button(root, text='<Add Time Input>', fg="Red", command=addBox)
addboxButton.pack()
root.mainloop()
#------------------------------------
EDIT:
Example with boxes side by side.
I use new frame to keep entries side by side using grid().
This way I don't mix grid() with pack() in main window/frame.
I use len(all_entries) to get number of next free column.
from Tkinter import *
#------------------------------------
def addBox():
print "ADD"
# I use len(all_entries) to get nuber of next free column
next_column = len(all_entries)
# add label in first row
lab = Label(frame_for_boxes, text=str(next_column+1))
lab.grid(row=0, column=next_column)
# add entry in second row
ent = Entry(frame_for_boxes)
ent.grid(row=1, column=next_column)
all_entries.append( ent )
#------------------------------------
def showEntries():
for number, ent in enumerate(all_entries):
print number, ent.get()
#------------------------------------
all_entries = []
root = Tk()
showButton = Button(root, text='Show all text', command=showEntries)
showButton.pack()
addboxButton = Button(root, text='<Add Time Input>', fg="Red", command=addBox)
addboxButton.pack()
frame_for_boxes = Frame(root)
frame_for_boxes.pack()
root.mainloop()
#------------------------------------
EDIT:
Another example:
from Tkinter import *
#------------------------------------
def addBox():
print "ADD"
frame = Frame(root)
frame.pack()
Label(frame, text='From').grid(row=0, column=0)
ent1 = Entry(frame)
ent1.grid(row=1, column=0)
Label(frame, text='To').grid(row=0, column=1)
ent2 = Entry(frame)
ent2.grid(row=1, column=1)
all_entries.append( (ent1, ent2) )
#------------------------------------
def showEntries():
for number, (ent1, ent2) in enumerate(all_entries):
print number, ent1.get(), ent2.get()
#------------------------------------
all_entries = []
root = Tk()
showButton = Button(root, text='Show all text', command=showEntries)
showButton.pack()
addboxButton = Button(root, text='<Add Time Input>', fg="Red", command=addBox)
addboxButton.pack()
root.mainloop()
#------------------------------------
First of all, the indentation is a whole mess, so I don't know where does the addBox function end ..
Second, I don't think you need a button, I suppose a checkbutton will do the same thing and it's also more common and familiar to users, I once had this problem and I simply created an entry box and put above it a label indicating that it's optional, and as for code, I simply ignored it if it was empty and verified the input if I found any input ..Howerver, that was for only one entry box, and you probably will need something more complex ..
See this ..
class OptionsView(Frame):
"""Frame for options in main window"""
def __init__(self, x, y, parent):
Frame.__init__(self, parent)
self.x = x
self.y = y
self.placed = False
self.hidden = False
self.btn = Button(self, text = 'Button attached to the frame ..', command = lambda: print('Button in frame clicked ..')).pack()
def pack(self):
self.place(x = self.x, y = self.y)
self.placed = True
def toggle_view(self):
if self.hidden:
self.pack()
self.hidden = False
else:
self.place_forget()
self.hidden = True
if __name__ == '__main__':
def m_frame():
if val.get() and not options_frame.placed:
print('Showing Frame ..')
options_frame.pack()
else:
print('Toggling Frame ..')
options_frame.toggle_view()
root = Tk()
root.geometry('300x400+500+600')
root.title('Testing Hiding Frames ..')
options_frame = OptionsView(200, 300, root)
val = BooleanVar(value = False)
Checkbutton(text = 'View more Options ..', var = val, command = m_frame).place(x=root.winfo_height()/2, y=root.winfo_width()/2)
try: root.mainloop()
except e: showerror('Error!', 'It seems there\'s a problem ..', str(e))
Ofcourse you can also modify the length and the x axis of the main window if you want to be more realistic ..

Categories

Resources