I am new in Oython. I wrote a simple calculator I can't understand How the function that we called it to "evaluate" works.
I have known that we have the local variables in the functions and the functions cant change the variables outside the function except we define it as output,
But in this function, It changes an outside variable and defines a new label.
I expect that we input ans as an input and take an output. and another strange problem is that we didn't give e as input but this function takes variable e with e.get() comment. How does the function know that we have a variable e when we didn't give it to the function,
My second question is how does "configure" work?
This is my code:
from tkinter import*
root=Tk()
label1 = Label(root,text="Enter your expression:")
label1.pack()
def evaluate(event):
data=e.get()
ans.configure(text="Answer:"+ str(eval(data)))
e = Entry(root)
e.bind("<Return>",evaluate)
e.pack()
ans = Label(root)
ans.pack()
root.mainloop()
The reason your function works is because Python is someone accepting of this situation.
Python will first try to edit a local variable when it cannot find ans as a local variable it then assumes it must be in the global name space and then checks there. This does not always work but can if the condition are right.
Here is a code example that shows where the function will guess correctly that your variable is in global and one function that fails at it.
import tkinter as tk
root = tk.Tk()
def print_some_number():
some_number = some_number + 5
print(some_number)
def testing():
lbl.configure(text="After button press")
some_number = 5
lbl = tk.Label(root, text="Before button press")
lbl.pack()
tk.Button(root, text="Update lavel", command=testing).pack()
tk.Button(root, text="Print some number", command=print_some_number).pack()
root.mainloop()
The print statement function will fail because we try to assign a local variable before assignment. We know it has been assigned in global but the function wont check because it looks like we are trying to assign it locally. The way to fix this is by adding the global statement like below:
import tkinter as tk
root = tk.Tk()
def print_some_number():
global some_number # global added here for this kind of fuction
some_number = some_number + 5
print(some_number)
def testing():
lbl.configure(text="After button press")
some_number = 5
lbl = tk.Label(root, text="Before button press")
lbl.pack()
tk.Button(root, text="Update lavel", command=testing).pack()
tk.Button(root, text="Print some number", command=print_some_number).pack()
root.mainloop()
Related
I was wondering how to make this code work.I always get 12 in the console.
from tkinter import *
s = 12
root = Tk()
root.geometry("200x200")
root.title("Program")
e = Entry(root)
e.pack()
def clicked():
e.get = s
print(s)
button = Button(root,command=clicked,text="ok")
button.pack()
root.mainloop()
You have to change the function clicked as follows:
def clicked():
s=e.get()
print(s)
There were two errors in your code:
You were trying to assign the value 12 to a function.
You were not calling the function (using parenthesis).
this line here:
e.get = s
says the method of e named get is equally to s.
Which is nonsense. You want s to be equally to what is returned by e.get.
to have something returned you need to invoke this method first.
So the logical right way to do this is by:
s = e.get()
Note that it is a variable in the enclosed namespaces of your function.
To make it global you need to global the variable.
from tkinter import *
s = 12
root = Tk()
root.geometry("200x200")
root.title("Program")
e = Entry(root)
e.pack()
def clicked():
#global s
s = e.get()
print(s)
button = Button(root,command=clicked,text="ok")
button.pack()
b2 = Button(root, text='print', command=lambda:print(s))
b2.pack()
root.mainloop()
I have used .place() instead of .pack() and placed my same entry on the same position as it was place before, but this time if value changes as you click on button OK.
Use e.insert(0,"Value") to insert any value in a entry.
This worked for me. Also let me know did it worked for you as well?
from tkinter import *
s = 12
root = Tk()
root.geometry("200x200")
root.title("Program")
e = Entry(root)
e.place(relx=0.1, rely = 0.1)
def clicked():
e = Entry(root)
e.insert(0, s)
e.place(relx=0.1, rely = 0.1)
button = Button(root,command=clicked,text="ok")
button.place(relx=0.4, rely = 0.2)
root.mainloop()
I'm trying to get a name from an user with Entry() function from Tkinter and then assign it to the variable Name, so that I can use it later. To check if the assignment works, I call the ready function, which makes Label with my variable. When i use 'e_name.get()' in 'command=' it works but when i use 'name' it doesn't. I guess I've messed up in order of code lines, but I'm not sure.
Here is the python code:
from tkinter import *
root = Tk()
e_name = Entry(root, width=50)
e_name.pack()
name = e_name.get()
def ready():
test = Label(root, text= name) #and this works >>> test = Label(root, text= e_name.get())
test.pack()
ready_button = Button(root, text="Next", command=ready)
ready_button.pack()
root.mainloop()
Declare name as global to access it outside of ready() function:
1) Initialize name = '' before def ready()
2) Add global name as first line in ready()
3) Add a new Get Name button
4) Add a new label below Get Name button to display the global name variable upon clicking Get Name button
5) Add function get_name() which uses global name to configure the new label with the last value stored by the ready() function.
It isn't pretty, but this working code demonstrates how to use name outside of ready function thanks to global. Test it by editing entry value, clicking Next button, then clicking Get Name button. The Get Name clicks will change the label directly under it to reflect the last value stored in global name by the ready() function.
If you edit the entry value and press the Get Name button it will not display the new value (it will continue to show previous value) in the new label until you click the Next button, because that is where global name variable is changed. I think this is the behavior you desire:
Here is the full working code:
from tkinter import *
root = Tk()
e_name = Entry(root, width=50)
e_name.pack()
name = ''
def ready():
global name
name = e_name.get()
test = Label(root, text= name) #and this works >>> test = Label(root, text= e_name.get())
test.pack()
def get_name():
global name
test2.configure(text= name)
ready_button = Button(root, text="Next", command=ready)
ready_button.pack()
name_button = Button(root, text="Get Name", command=get_name)
name_button.pack()
test2 = Label(root)
test2.pack()
root.mainloop()
So I'm trying to make it cycle through each letter of the alphabet when the button is clicked.
I have tried the method i am showing now.
I have also tried many others and i couldn't get anything to work.
If you do have a solution please try keep it simple i am kinda new too this.
from tkinter import *
win = Tk()
win.title('ab')
a = 0
def changetext():
a = a+1
if a == 1:
lbl.config(text='b')
def changetext():
if a == 2:
lbl.config(text='c')
lbl = Label(win,text='a')
lbl.grid(row=1,column=1)
btn = Button(win,text='u', command =changetext)
btn.grid(row=2,column=1)
win.mainloop()```
In python, variables inside functions are local, which means that if you define a variable a = 0 outside the function, then do a = 1 in the function, the a equals 1 inside the function but it still equals 0 outside. If you want to change the value of a outside the function from inside the function, you need to declare a as a global variable (see code below).
import tkinter as tk # avoid import * to because it leads to naming conflicts
win = tk.Tk()
win.title('ab')
i = 0
letters = "abcdefghijklmnopqrstuvwxyz"
def changetext():
global i # change value of i outside function as well
i += 1
i %= 26 # cycle through the alphabet
lbl.configure(text=letters[i])
lbl = tk.Label(win, text='a')
lbl.grid(row=1, column=1)
btn = tk.Button(win,text='u', command=changetext)
btn.grid(row=2, column=1)
win.mainloop()
You can use itertools.cycle to create a cycle list and then use next() function to get the next item in the cycle list:
import tkinter as tk
from itertools import cycle
words = cycle(['hello', 'world', 'python', 'is', 'awesome'])
root = tk.Tk()
lbl = tk.Label(root, text=next(words), width=20)
lbl.pack()
tk.Button(root, text='Next', command=lambda: lbl.config(text=next(words))).pack()
root.mainloop()
I actually used the first method and adapted it by making the variable global because then it will update it for all the functions making my first method work
from tkinter import *
win = Tk()
win.title('ab')
i = 0
def changetext():
global i
i = i + 1
if i == 1:
lbl.config(text='word 2')
if i == 2:
lbl.config(text='word 1 ')
lbl = Label(win,text='a')
lbl.grid(row=1,column=1)
btn = Button(win,text='u', command =changetext)
btn.grid(row=2,column=1)
win.mainloop()
I'm trying to wrap my head around this problem.
Say I have a code like this:
def get_input(data_A, data_B):
all_data = [data_A.get(),dataB.get()]
return(all_data)
def the_gui():
root = Tk()
data_A = Entry(root)
data_B = Entry(root)
button = Button(root, text='Submit', command=lambda: get_input(data_A, data_B))
mainloop()
My goal is to get the value of data_A and data_B once I clicked the submit button.
I tried to use global variable and everything, but I kept failing to catch the value.
The only thing that works is when I put the whole get_input() function inside the_gui() function. However, I don't think that's a good practice to implement.
Any suggestions?
Here is a simple example of how you could write this to get the results you are looking for.
When using global is that all your root window and related fields are in a function. So you would have to define global in both function and this is not what you want to do.
Typically you will want to write the root window in the global namespace and not in a function or write it into a class so you can avoid global's all-together.
button = Button(...) may not be doing what you think it is. This does not return a value from the command once clicked. Tkinter buttons do not care about anything being returned. So you have to record that value elsewhere.
I am not sure how you code is working as you do not use geometry managers and mainloop() should be attached to the root window so I have added those in as well.
Example 1:
import tkinter as tk
def get_input():
global a_and_b
a_and_b = [data_a.get(), data_b.get()]
# If you want to keep a running record of all values submitted
# then you can do this instead:
# a_and_b.append([data_a.get(), data_b.get()])
def print_a_b():
print(a_and_b)
root = tk.Tk()
a_and_b = []
data_a = tk.Entry(root)
data_b = tk.Entry(root)
data_a.pack()
data_b.pack()
tk.Button(root, text='Submit', command=get_input).pack()
tk.Button(root, text='Print A/B List', command=print_a_b).pack()
root.mainloop()
Example 2 using OOP:
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.a_and_b = []
self.data_a = tk.Entry(self)
self.data_b = tk.Entry(self)
self.data_a.pack()
self.data_b.pack()
tk.Button(self, text='Submit', command=self.get_input).pack()
tk.Button(self, text='Print A/B List', command=self.print_a_b).pack()
def get_input(self):
self.a_and_b = [self.data_a.get(), self.data_b.get()]
def print_a_b(self):
print(self.a_and_b)
if __name__ == '__main__':
App().mainloop()
This program is being written in Tkinter. I am writing a program that will have multiple entry boxes where the user will input certain parameters. I want there to be a single button that saves all the entries from all the entry boxes to be used later by another part of my program. At this moment, the entry boxes and the button are done but the button does not do anything. How could I go about making the button read and save all the entries? Thanks!
You just need to get the data in the Entries and store them as variables, inside functions and globalize those variables. After that just call all the functions in a separate function. And then give this function as a command to the button.
import tkinter as tk
root = tk.Tk()
e_1 = tk.Entry(root)
e_1.pack()
e_2 = tk.Entry(root)
e_2.pack()
e_3 = tk.Entry(root)
e_3.pack()
var_1 = 0
var_2 = 0
var_3 = 0
def func_1():
global var_1
var_1 = e_1.get()
def func_2():
global var_2
var_2 = e_2.get()
def func_3():
global var_3
var_3 = e_3.get()
def store_all():
func_1()
func_2()
func_3()
print(var_1)
print(var_2)
print(var_3)
b = tk.Button(root, text="get", width=10, command=store_all)
b.pack()
root.mainloop()
I have used print() inside the function to confirm to you that the values are stored successfully. You can just remove those.
Here is an example of a program that reads contents of one Entry and prints it:
https://effbot.org/tkinterbook/entry.htm#patterns
Below you can find code in python 3:
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()
mainloop()
Just add more Entry widgets and read them all in the callback method.