Reputation: 33
I want to write a small app that counts net amount and tax. I wrote this code and I've tried many times using var.set()
based on this post but I have no idea how do it correctly.
from tkinter import *
import tkinter as tk
def count23():
b = gross.get()
n = round(b/1.23, 2)
v = round(b - n, 2)
# print here works, but prints in shell
def count8():
b = gross.get()
n = round(b/1.08, 2)
v = round(b - n, 2)
def count5():
b = gross.get()
n = round(b/1.05, 2)
v = round(b - n, 2)
root = tk.Tk()
gross = DoubleVar()
root.geometry('220x200+250+250')
L1 = Label(root, text='Input gross ammount').grid(row=0, column=0, columnspan=5)
E1 = Entry(root, textvariable=gross).grid(row=1, column=1, columnspan=3, sticky='WE', padx=5, pady=5)
L2 = Label(root, text='Choose your tax rate').grid(row=2, column=0, columnspan=5)
B1 = Button(root, text='5 %', command=count5)
B1.grid(row=3, column=0, padx=5, pady=5)
B2 = Button(root, text='8 %', command=count8)
B2.grid(row=3, column=2, padx=5, pady=5)
B3 = Button(root, text='23 %', command=count23)
B3.grid(row=3, column=4, padx=5, pady=5)
L3 = Label(root, text=' ').grid(row=4, column=0, columnspan=5)
L4 = Label(root, text='Net').grid(row=5, column=0, columnspan=2, sticky='WE')
L5 = Label(root, text='TAX').grid(row=5, column=3, columnspan=2, sticky='WE')
L6 = Label(root, relief='raised')
L6.grid(row=6, column=0, columnspan=2, sticky='WE')
L7 = Label(root, relief='raised')
L7.grid(row=6, column=3, columnspan=2, sticky='WE')
root.mainloop()
I need to print net and tax in L6 and L7 labels. Give me some clues how do it, please.
Upvotes: 1
Views: 11146
Reputation: 55469
The simple way to do this is to give those labels their own textvariable
s.
I replaced your 3 count
functions with a single function show_tax
. We use lambda functions in each Button command to call show_tax
with the desired tax rate. I've also made a few other minor changes.
import tkinter as tk
def show_tax(rate):
b = gross.get()
n = round(b / rate, 2)
# Format to string with 2 digits after the decimal point
net.set(format(n, '.2f'))
t = round(b - n, 2)
tax.set(format(t, '.2f'))
root = tk.Tk()
root.geometry('310x165+250+250')
root.title('Tax calculator')
gross = tk.DoubleVar()
net = tk.StringVar()
tax = tk.StringVar()
tk.Label(root, text='Input gross amount').grid(row=0, column=0, columnspan=5)
e = tk.Entry(root, textvariable=gross)
e.grid(row=1, column=1, columnspan=3, sticky='WE', padx=5, pady=5)
tk.Label(root, text='Choose your tax rate').grid(row=2, column=0, columnspan=5)
b = tk.Button(root, text='5 %', command=lambda r=1.05: show_tax(r))
b.grid(row=3, column=0, padx=5, pady=5)
b = tk.Button(root, text='8 %', command=lambda r=1.08: show_tax(r))
b.grid(row=3, column=2, padx=5, pady=5)
b = tk.Button(root, text='23 %', command=lambda r=1.23: show_tax(r))
b.grid(row=3, column=4, padx=5, pady=5)
# An empty Label to force row to be displayed
tk.Label(root).grid(row=4, column=0, columnspan=5)
tk.Label(root, text='Net').grid(row=5, column=0, columnspan=2, sticky='WE')
tk.Label(root, text='TAX').grid(row=5, column=3, columnspan=2, sticky='WE')
l = tk.Label(root, textvariable=net, relief='raised')
l.grid(row=6, column=0, columnspan=2, sticky='WE')
l = tk.Label(root, textvariable=tax, relief='raised')
l.grid(row=6, column=3, columnspan=2, sticky='WE')
root.mainloop()
I have a couple more comments on your code (and my changes to it).
It's not a good idea to use from tkinter import *
as that imports about 130 Tkinter names into the global namespace, which is messy and can lead to name collisions. Using the explicit tk.
form makes the code easier to read.
BTW, the Widget .grid
and .pack
methods return None
. So when you do something like
L2 = Label(root, text='Choose your tax rate').grid(row=2, column=0, columnspan=5)
it creates the label, puts it into the grid, and then sets L2
to None
. If you need to keep a reference to the label you need to create the widget & place it into the grid in two steps, like this:
L2 = Label(root, text='Choose your tax rate')
L2.grid(row=2, column=0, columnspan=5)
If you don't need to keep a reference to the widget, but you still want to split it over 2 lines to keep the line length short then just use a "throwaway" variable, like I have with e
, b
, and l
.
As Bryan Oakley mentions in the comments we don't actually need to give those labels their own StringVar textvariable
s: we can directly update their text
s using the widget's .config
method.
import tkinter as tk
def show_tax(rate):
b = gross.get()
n = round(b / rate, 2)
# Format to string with 2 digits after the decimal point
L6.config(text=format(n, '.2f'))
t = round(b - n, 2)
L7.config(text=format(t, '.2f'))
root = tk.Tk()
root.geometry('310x165+250+250')
root.title('Tax calculator')
gross = tk.DoubleVar()
tk.Label(root, text='Input gross amount').grid(row=0, column=0, columnspan=5)
e = tk.Entry(root, textvariable=gross)
e.grid(row=1, column=1, columnspan=3, sticky='WE', padx=5, pady=5)
tk.Label(root, text='Choose your tax rate').grid(row=2, column=0, columnspan=5)
b = tk.Button(root, text='5 %', command=lambda r=1.05: show_tax(r))
b.grid(row=3, column=0, padx=5, pady=5)
b = tk.Button(root, text='8 %', command=lambda r=1.08: show_tax(r))
b.grid(row=3, column=2, padx=5, pady=5)
b = tk.Button(root, text='23 %', command=lambda r=1.23: show_tax(r))
b.grid(row=3, column=4, padx=5, pady=5)
# An empty Label to force row to be displayed
tk.Label(root).grid(row=4, column=0, columnspan=5)
tk.Label(root, text='Net').grid(row=5, column=0, columnspan=2, sticky='WE')
tk.Label(root, text='TAX').grid(row=5, column=3, columnspan=2, sticky='WE')
L6 = tk.Label(root, relief='raised')
L6.grid(row=6, column=0, columnspan=2, sticky='WE')
L7 = tk.Label(root, relief='raised')
L7.grid(row=6, column=3, columnspan=2, sticky='WE')
root.mainloop()
Upvotes: 4