Python tkinter label formulas - python

how can I make a label with a formula and whenever I change the value in entry, does it automatically change the value in the label? As if it were excel cells with formulas. And in case it would have to be invisible (without content) while the entry is empty.
import tkinter as tk
root = tk.Tk()
ent1 = tk.Entry(root)
lab1 = tk.Label(root,text='Price')
ent2 = tk.Entry(root)
lab2 = tk.Label(root,text='Quantity')
lab3 = tk.Label(root,text='') #lab3 formula = float(ent1.get()) * int(ent2.get())
lab1.pack()
ent1.pack()
lab2.pack()
ent2.pack()
lab3.pack()

Use the trace method to execute a function when a variable changes.
import tkinter as tk
def update(*args):
try:
output_var.set(price_var.get() * quantity_var.get())
except (ValueError, tk.TclError):
output_var.set('invalid input')
root = tk.Tk()
lab1 = tk.Label(root,text='Price')
price_var = tk.DoubleVar()
price_var.trace('w', update) # call the update() function when the value changes
ent1 = tk.Entry(root, textvariable=price_var)
lab2 = tk.Label(root,text='Quantity')
quantity_var = tk.DoubleVar()
quantity_var.trace('w', update)
ent2 = tk.Entry(root, textvariable=quantity_var)
output_var = tk.StringVar()
lab3 = tk.Label(root, textvariable=output_var) #lab3 formula = float(ent1.get()) * int(ent2.get())
lab1.pack()
ent1.pack()
lab2.pack()
ent2.pack()
lab3.pack()
root.mainloop()

Related

how can I print the return value of a function to entry in tinker?

from tkinter import *
def c_to_f(celsius):
return str(float(celsius) * 1.8 + 32)
window = Tk()
f = Label(window, text="ºF")
f.pack()
finpt = Entry(window)
fvalue = finpt.get()
finpt.pack()
c = Label(window, text="ºC")
c.pack()
cinpt = Entry(window)
cvalue = cinpt.get()
cinpt.pack()
to_f = Button(window, text="Nach ºF umrechnen", command=finpt.insert(0, f"{c_to_f(cvalue)}"))
to_f.pack()
window.mainloop()
After pressing the button, I want to return the show the result of c_to_f(cvalue) in Label c. How can I manage that?
It is better to create another function for the button to_f and do the conversion and show result inside that function:
from tkinter import *
def c_to_f(celsius):
return str(float(celsius) * 1.8 + 32)
def convert_to_fahrenheit():
try:
f = c_to_f(cinpt.get())
finpt.delete(0, END)
finpt.insert(END, f)
except ValueError as ex:
print(ex)
window = Tk()
f = Label(window, text="ºF")
f.pack()
finpt = Entry(window)
#fvalue = finpt.get()
finpt.pack()
c = Label(window, text="ºC")
c.pack()
cinpt = Entry(window)
#cvalue = cinpt.get()
cinpt.pack()
to_f = Button(window, text="Nach ºF umrechnen", command=convert_to_fahrenheit)
to_f.pack()
window.mainloop()
Your code is giving too much problem.
Try this:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.title('Temperature Converter')
root.geometry('300x70')
root.resizable(False, False)
def fahrenheit_to_celsius(f):
""" Convert fahrenheit to celsius
"""
return (f - 32) * 5/9
frame = ttk.Frame(root)
options = {'padx': 5, 'pady': 5}
temperature_label = ttk.Label(frame, text='Fahrenheit')
temperature_label.grid(column=0, row=0, sticky='W', **options)
temperature = tk.StringVar()
temperature_entry = ttk.Entry(frame, textvariable=temperature)
temperature_entry.grid(column=1, row=0, **options)
temperature_entry.focus()
def convert_button_clicked():
f = float(temperature.get())
c = fahrenheit_to_celsius(f)
result = f'{f} Fahrenheit = {c:.2f} Celsius'
result_label.config(text=result)
convert_button = ttk.Button(frame, text='Convert')
convert_button.grid(column=2, row=0, sticky='W', **options)
convert_button.configure(command=convert_button_clicked)
result_label = ttk.Label(frame)
result_label.grid(row=1, columnspan=3, **options)
frame.grid(padx=10, pady=10)
root.mainloop()
Screenshot:

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.

How to insert image into different columns in tkinter Treeview widget?

I just want, that image was in specified (in column named 'Country') column instead of first. Thanks!
from tkinter import ttk
from tkinter import *
root = Tk()
s = ttk.Treeview(columns=('#1', '#2'))
s.heading('#0', text='Ip')
s.heading('#1', text='Port')
s.heading('#2', text='Country')
s.pack()
v = PhotoImage(file='uk.png')
s.insert('', 2, values=('127.0.0.1', '8888'), image=v)
root.mainloop()
I've made it simple :) just starting with country
from tkinter import ttk
from tkinter import *
root = Tk()
s = ttk.Treeview(columns=('#1', '#2'))
s.heading('#0', text='Country')
s.heading('#1', text='Ip')
s.heading('#2', text='Port')
v = PhotoImage(file='uk.png')
s.insert('', 2, values = ('127.0.0.1', '8888'), image=v)
s.pack()
root.mainloop()
If you don't like the image in the first place, I can imagine this, without treeview, though
from tkinter import ttk
from tkinter import *
root = Tk()
v = PhotoImage(file='uk.png')
# header
b = Label(root, text="Ip")
b.grid(row=0, column=0)
b = Label(root, text="port")
b.grid(row=0, column=1)
b = Label(root, text="Country")
b.grid(row=0, column=2)
lista = [["800","127.1.1.",v]]
height = 2
width = 3
for i in range(height-1): #Rows
b1 = Label(root, text=lista[i][0])
b1.grid(row=i+1, column=0)
b2 = Label(root, text=lista[i][1])
b2.grid(row=i+1, column=1)
b3 = Label(root, image=lista[i][2])
b3.grid(row=i+1, column=2)
mainloop()

How to clear a label using tkinter when pressing a button?

I am using labels to show a generated password in my tkinter password generator program, but when I change the length of a password from a lower value than before (for example from a length of 20 to 10) the label displaying the password appears to be overwritten - it does not clear. I have searched methods to do this, but I cannot seem to find any.
Here is my code:
from tkinter import *
from random import *
import string
root = Tk()
root.wm_title("Password Generator")
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
root.geometry("1000x1000")
title = Label(topFrame, text="Length", fg="blue")
title.grid(row=3,column=5)
var = DoubleVar()
Slider_1 = Scale(root,orient=HORIZONTAL,length=32*10,from_=0,to=32, variable
= var)
Slider_1.pack()
passLen = var.get()
uppercaseLetters = "QWERTYUIOPASDFGHJKLZXCVBNM"
lowercaseLetters = "qwertyuiopasdfghjklzxcvbnm"
symbols = "!£$%^&*()_+-=}{][~##':;?>/.<,"
digits = "1234567890"
def gen():
characters = uppercaseLetters + lowercaseLetters + symbols + digits
password = "".join(choice(characters) for x in range(int(var.get())))
passLabel = Label(topFrame, text=password)
passLabel.grid(row=4, column=5)
genButton = Button(topFrame, text="Generate Password", fg="blue",
command=gen)
genButton.grid(row=1, column=5)
root.mainloop()
When I set the length to 32 characters:
And when I set the length to 6 characters it does not clear the old password label - it simply overwrites it in the middle of the old password label:
First of all, move your gen method definition to just below imports so that they're recognized in the main body. Then take your widgets and mainloop out of the method. Just configure passLabel's text when needed:
def gen():
characters = uppercaseLetters + lowercaseLetters + symbols + digits
password = "".join(choice(characters) for x in range(int(var.get())))
passLabel['text'] = password
Entire code with suggested edits been made:
from tkinter import *
from random import *
import string
def gen():
characters = uppercaseLetters + lowercaseLetters + symbols + digits
password = "".join(choice(characters) for x in range(int(var.get())))
passLabel['text'] = password
root = Tk()
root.wm_title("Password Generator")
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
root.geometry("1000x1000")
title = Label(topFrame, text="Length", fg="blue")
title.grid(row=3,column=5)
var = DoubleVar()
Slider_1 = Scale(root,orient=HORIZONTAL,length=32*10,from_=0,to=32, variable
= var)
Slider_1.pack()
passLen = var.get()
uppercaseLetters = "QWERTYUIOPASDFGHJKLZXCVBNM"
lowercaseLetters = "qwertyuiopasdfghjklzxcvbnm"
symbols = "!£$%^&*()_+-=}{][~##':;?>/.<,"
digits = "1234567890"
passLabel = Label(topFrame)
passLabel.grid(row=4, column=5)
genButton = Button(topFrame, text="Generate Password", fg="blue",
command=gen)
genButton.grid(row=1, column=5)
root.mainloop()
Change two things:
First:
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
passLabel = Label(topFrame)
root.geometry("1000x1000")
Second:
def gen():
characters = uppercaseLetters + lowercaseLetters + symbols + digits
password = "".join(choice(characters) for x in range(int(var.get())))
passLabel.config(text=password)
passLabel.grid(row=4, column=5)
"How to clear a label using tkinter when pressing a button?"
Below is an example that clears label's text when the button is pressed:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def clear_widget_text(widget):
widget['text'] = ""
if __name__ == '__main__':
root = tk.Tk()
label = tk.Label(root, text="This will be cleared.")
button = tk.Button(root, text="Clear",
command=lambda : clear_widget_text(label))
label.pack()
button.pack()
root.mainloop()
Below is an example that destroys label when button is pressed:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def clear_widget(widget):
widget.destroy()
if __name__ == '__main__':
root = tk.Tk()
label = tk.Label(root, text="This will be cleared.")
button = tk.Button(root, text="Clear",
command=lambda : clear_widget(label))
label.pack()
button.pack()
root.mainloop()

How to overwrite data in text file in tkinter

I am creating a program with tkinter which comes with a default name and password stored in a text file. After login you need to open the Toplevel window and type in the name and password you want to use in your subsequent logins. I have defined my variables but if I want to overwrite the text file I receive the below:
Error "NameError: name 'e1' is not defined"
Which I know I have defined.
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20).pack()
e2 = Entry(ch, width=20).pack()
sb = Button(ch, text="save", command=save_changes).pack()
def save_changes(): # function to change data in the txt file
data = e1.get() + "\n " + e2.get()
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
So you have a few options here but in general you have 2 major issues.
The first issue is the use of .pack() after the creation of your e1 and e2 entry fields. This is a problem for the get() method as the geometry manager will return None if you pack this way. The correct method is to create the widget first with e1 = Entry(ch, width=20) and then pack it on the next line with e1.pack() this will allow get() to work on e1.
The second issue is the matter of local variables vs global variables. You have created e1 and e2 inside of the function change_login() and without telling python that e1 and e2 are global variables it will automatically assume you want them as local variables. This means the variables are only accessible from within the function they are created in.
You have a few options and I will break them out for you.
1) The quick and dirty option is to assign e1 and e2 as global variables. This can be done by using global var_name, var2_name, and_so_on so in this case add this line to the top of your change_login(): and save_changes() functions:
global e1, e2
This well tell python to add e1 and e2 to the global name space and it will allow save_changes() to work with the variables in the global name space.
2) Another method is to pass the 2 variables to save_changes() using the button command. We will need to use lambda for this and we can accomplish this by adding:
command = lambda e1=e1, e2=e2: save_changes(e1, e2)
to the button created in change_login() and adding the 2 arguments to save_changes() like this:
save_changes(e1, e2)
This will work just as well as the first option and it also avoids the use of global variables.
3) A third option is to create the entire program as a class and to use class attributes to allow the variables to work with all methods within the class.
Below is an example of your code using the 1st option:
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
global e1, e2
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20)
e1.pack()
e2 = Entry(ch, width=20)
e2.pack()
sb = Button(ch, text="save", command=save_changes).pack()
def save_changes(): # function to change data in the txt file
global e1, e2
data = e1.get() + "\n" + e2.get() # removed space after \n
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
Below is an example of your code using the 2nd option:
import sys
from tkinter import messagebox
from tkinter import *
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login():
ch = Toplevel(root)
ch.geometry('300x300')
e1 = Entry(ch, width=20)
e1.pack()
e2 = Entry(ch, width=20)
e2.pack()
Button(ch, text="save", command=lambda e1=e1, e2=e2: save_changes(e1, e2)).pack()
def save_changes(e1, e2): # function to change data in the txt file
data = e1.get() + "\n" + e2.get() # removed space after \n
with open("pass.txt", "w") as f:
f.writelines(data)
root= Tk()
log = Toplevel()
root.geometry("350x350")
log.geometry("200x200")
entry1 = Entry(log)
entry2 = Entry(log)
button1 = Button(log, text="Login", command=login_in) #Login button
entry1.pack()
entry2.pack()
button1.pack()
label = Label(root, text="welcome").pack()
butt = Button(root, text="change data in file", command=change_login).pack()
root.withdraw()
root.mainloop()
Below is an example of your code converted to a class and using class attributes to avoid the use of global variables.
import sys
from tkinter import messagebox
from tkinter import *
class MyApp(Frame):
def __init__(self, master, *args, **kwargs):
Frame.__init__(self, master, *args, **kwargs)
self.master = master
self.master.withdraw()
self.log = Toplevel()
self.master.geometry("350x350")
self.log.geometry("200x200")
self.entry1 = Entry(self.log)
self.entry2 = Entry(self.log)
self.button1 = Button(self.log, text="Login", command=self.login_in)
self.entry1.pack()
self.entry2.pack()
self.button1.pack()
Label(root, text="welcome").pack()
Button(root, text="change data in file", command=self.change_login).pack()
def login_in(self):
with open("pass.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if self.entry1.get() == name and self.entry2.get() == password:
self.master.deiconify()
self.log.destroy()
else:
messagebox.showerror("error","login Failed")
def change_login(self):
ch = Toplevel(self.master)
ch.geometry('300x300')
self.e1 = Entry(ch, width=20)
self.e1.pack()
self.e2 = Entry(ch, width=20)
self.e2.pack()
Button(ch, text="save", command=self.save_changes).pack()
def save_changes(self):
data = "{}\n{}".format(self.e1.get(), self.e2.get())
with open("pass.txt", "w") as f:
f.writelines(data)
if __name__ == "__main__":
now = open("pass.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
root = Tk()
app = MyApp(root)
root.mainloop()

Categories

Resources