I am trying to use tkinter to have a user input variables to pass it into a function. The problem is , the input from the user is not being assigned to the actual variable for whatever reason.
root = Tk()
root.geometry("600x300")
MainWindow = Label(root, text = "Input var:")
MainWindow.grid(row=0, column = 0)
var= Entry(root)
var.grid(row=0, column=1)
I have about 20 variables being asked for in the GUI that has similar code to the above.
I then assign a button to display what is assigned to the variable (for troubleshooting purposes, the original purpose of the button is to pass the variables into a function).
buttonGo=Button(root, text="Generate", command= lambda: print(f'Var is : {var}'))
buttonGo.grid(row=20, column=1)
buttonExit
buttonExit.grid(row=20, column=2)
root.mainloop()
When I run the program and click on the "Generate" button, I get the below output and not what I define it in the program.
Var is : .!entry
That .!entry is the widget, not the value. If you want the value, you need to use the get() method of the widget.
In other words, something like:
value = var.get()
# Now use value.
Based on the replies I got, I believe I found the answer to be using .get method when calling the function. I modified the line to:
buttonGo=Button(root, text="Generate", command= lambda: print(f'Var is : {var.get()}'))
Thanks for the replies and explanations.
Related
I'm trying to make a button that saves your username but then goes away after you set it.
this is my code:
def printValue():
User = Name.player_name.get()
label.config(text=f'Hi, {User}')
Name.button.destroy()
Name.player_name.destroy()
def Name():
label.config(text="What's your name?")
Name.player_name = Entry(root)
Name.player_name.pack(pady=15)
Name.button = Button(text="Change", command=printValue)
Name.button.pack()
The code below, with some minor changes like enabling change with [Return] and some layout cosmetics works OK (also with un-commented lines in printValue) . If you want the [Change] button and the entry area to go away un-comment the two lines turned into comments in the printValue function:
# https://stackoverflow.com/questions/72671126/tkinter-destroying-an-object-in-a-different-function-isnt-working
from tkinter import Tk, mainloop, Entry, Button, Label
root = Tk()
label = Label(root, font=('',12), padx=15, pady=5)
label.pack()
def Name():
label.config(text="What's your name?")
Name.player_name = Entry(root, font=('',12))
Name.player_name.pack(padx=15, pady=15)
Name.player_name.focus()
Name.button = Button(text="Change", command=printValue)
Name.button.pack()
def printValue(event=None):
User = Name.player_name.get()
# Name.player_name.destroy()
# Name.button.destroy()
label.config(text=f'Hi, {User}')
Name()
root.bind("<Return>", printValue)
mainloop()
By the way: The in the question provided code demonstrates an interesting approach of making names of variables global by setting function attributes in the function itself. This way it is possible to assign values in one function and retrieve them in another without passing return values or declaring variables global. I am not aware of already having seen such approach used in Python code here on stackoverflow. How does it come you use such code?
I am a beginner in python, I used tkinter to build a to-do list program. But the problem is I don't understand how it works.
from tkinter import *
root = Tk()
def insert_Task(name):
name = Checkbutton(root, text=name, command= lambda: del_task(name))
name.pack()
def del_task(name):
name.destroy()
insert_Entry = Entry(root)
insert_Button = Button(root, text="Ok", command=lambda: insert_Task(insert_Entry.get()))
insert_Entry.pack()
insert_Button.pack()
root.mainloop()
The only way this should work is when name is passed into text, it is insert_Entry.get() and when the function is called it is the Checkbutton object.
Can someone explain to me if this is the case?
lambdas are used to create anonymous functions. The code:
command=lambda: insert_Task(insert_Entry.get())
Can also be written as:
def click_next(): #=== any name
insert_Task(insert_Entry.get())
insert_Button=Button(....,command = click_next)
Why do we use lambda to pass arguments?
We need to pass the reference of the function, i.e without providing a (). Or else, the function is executed right away and the returned value is set as the command.
When you click on the button, insert_Entry.get() returns all the text which is entered in insert_Entry. This is passed as the argument in insert_Task where a Check button is created with that name.
Similarly:
name = Checkbutton(root, text=name, command= lambda: del_task(name))
in this, a reference of the Checkbutton is passed as an argument to del_task so that on clicking on it, the method in invoked and the selected check button is destroyed
I have a tkinter GUI which includes an Entry Widget (tk.Entry). At the moment this displays a numeric value, which can be incremented up/down by a couple of tkinter Buttons. In addition to incrementing the value displayed in the Entry Widget, whenever the Button is clicked it executes a command which updates the appropriate setting on a physical instrument with the new value from the Entry Widget.
I am wondering if it is possible at all to also have the option that if the user types a number into the Entry Widget to overwrite what is already there, that this can execute the same command as clicking the up/down buttons? For example, if the value is set to 10, and the user enters 100, then the command is executed to update the real instrument to 100.
I tried to add the code command=mycommandname to the Entry Widget (e.g. input_wavelength = tk.Entry(pwr_mtr_ctrl_frame, relief=tk.GROOVE, font=( "Ariel", 11), justify='center', validate='key', vcmd=pwr_vcmd, command=mycommandname) but get the error "unknown option "-command""
I guess this means that the Entry Widget does not have the option to execute a function, like a Button widget does? Are there ways to implement this somehow?
def print_something(*args):
print('hello world')
root = TK()
entry1 = Entry(root)
entry1.bind("<Return>", print_something)
# you can use other keys and replace it with "<Return>". EX: "f"
# by default, this function will pass an unknown argument to your function.
# thus, you have to give your function a parameter; in this case, we will use *args
root.mainloop()
According to what you described you would be better "served" by using a Spinbox.
This being said you need to bind a function to the <Return> event captured by the Entry if you want to execute something when the user enters something:
Here is how to do it:
input_wavelength = tk.Entry(pwr_mtr_ctrl_frame, relief=tk.GROOVE, font=( "Ariel", 11), justify='center', validate='key', vcmd=pwr_vcmd)
input_wavelength.bind("<Return>",mycommandname)
If mycommandname is also used as a command you need to declare it like this:
def mycommandname(event=None):
...
I have some pretty simple code right now that I am having issues with.
root = Tk()
label1 = Label(root, text ="Enter String:")
userInputString = Entry(root)
label1.pack()
userInputString.pack()
submit = Button(root,text = "Submit", command = root.destroy)
submit.pack(side =BOTTOM)
root.mainloop()
print(userInputString)
When I run the code everything operates as I would expect except
print(userInputString)
for an input asdf in the Entry print will return something like 0.9355325
But it will never be the same value back to back always random.
I am using python 3.5 and Eclipse Neon on a Windows 7 Machine.
Ultimately the goal is to accept a string from the user in the box that pops up and then be able to use that value as string later on. For example, it might be a file path that needs to be modified or opened.
Is Entry not the correct widget I should be using for this? Is there something inherently wrong with the code here? I am new to python and don't have a lot of strong programming experience so I am not even certain that this is set up right to receive a string.
Thanks in advance if anyone has any ideas.
There are two things wrong with your print statement. First, you print the widget, not the text in the widget. print(widget) prints str(widget), which is the tk pathname of the widget. The '.' represents the root window. The integer that follows is a number that tkinter assigned as the name of the widget. In current 3.6, it would instead be 'entry', so you would see ".entry".
Second, you try to print the widget text after you destroy the widget. After root.destroy, the python tkinter wrapper still exists, but the tk widget that it wrapped is gone. The following works on 3.6, Win10.
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text="Enter String:")
entry = tk.Entry(root)
def print_entry(event=None):
print(entry.get())
entry.bind('<Key-Return>', print_entry)
entry.focus_set()
submit = tk.Button(root, text="Submit", command=print_entry)
label.pack()
entry.pack()
submit.pack()
root.mainloop()
Bonus 1: I set the focus to the entry box so one can start typing without tabbing to the box or clicking on it.
Bonus 2: I bound the key to the submit function so one can submit without using the mouse. Note that the command then requires an 'event' parameter, but it must default to None to use it with the button.
The NMT Reference, which I use constantly, is fairly complete and mostly correct.
How do I pass parameters to a function through a button?
variable = str()
def RandomFunction(variable):
print (variable)
EntryBox = Entry(MainWindow, textvariable = variable).pack()
FunctionCall = Button(MainWindow, text="Enter", command=RandomFunction(variable))
It seems like it just doesnt print anything when the button is pressed. I've searched around and it seems that using lambda can fix it and allow (variable) to be passed to the function but after experimenting with lambda variable:variable I still can't get it to work.
The other answers here work, but like a lot of things in life, there's more than one way to do what you're trying to do.
The code in your question actually mixes a couple of methods of getting data from the Entry widget. You're using textvariable and lambda, but you only need one. It seems like lambda has been covered, so here's a quick answer about textvariable:
First, you need to make your variable of a Tkinter string type like this:
variable = StringVar()
Your entry widget is fine, it's connected to the StringVar(). Your button doesn't need lambda, though, because you don't need to pass an argument to your RandomFunction().
FunctionCall = Button(MainWindow, text='Enter', command=RandomFunction).pack()
Lastly, your function needs a little rework, because it's not taking an argument anymore, it's just going to use the .get() method on your StringVar() whenever it's called:
def RandomFunction():
print(variable.get())
You can read more about StringVar()s here: http://effbot.org/tkinterbook/variable.htm
You use .get() to get the contents of an Entry. From the effbot page http://effbot.org/tkinterbook/entry.htm
from Tkinter import *
master = Tk()
e = Entry(master)
e.pack()
e.focus_set()
def callback():
print e.get()
b = Button(master, text="get", width=10, command=callback)
b.pack()
master.mainloop()
Using lambda to create a function that calls the function with the argument is fine (as long as you do it correctly):
FunctionCall = Button(MainWindow, text="Enter", command=lambda: RandomFunction(EntryBox.get))
Python will be happy with this because the lambda doesn't take any arguments.