Python update user input with tkinter button - python

I'm just starting with python and i'm having a problem. I've tried various solutions, but i can't update the field that says '19'. When i click on plus, i want it to be 20, then 21,... and when i click - it has to go back to 20 , 19. Can anybody tell me how to solve this?
from tkinter import *
def fct_tempplus():
while True:
# tekstvak_input_user = tekstvak_input_user +1
return tekstvak_input_user + 1
def fct_tempmin():
print ('ok')
window = Tk()
window.geometry("800x400") # not *
window.title("TEST")
label= Label( window, text = "Temp?")
label.place(x=350,y=175)
tempplus=Button(window, bd=10,width=10, height = 1,text="+",command=fct_tempplus,
font=("Helvetica", 12))
tempplus.place(x=500,y=150)
tempmin=Button(window, bd=10,width=10, height = 1,text="-", font=("Helvetica", 12),command=fct_tempmin)
tempmin.place(x=500,y=200)
tekstvak_input_user = Entry(window, width = 10 )
tekstvak_input_user.insert(0,19.0)
tekstvak_input_user.place(x=350 , y=200)
window.mainloop()`

while True is not needed in this program. And you have to use .get() to get a value inside a function. And then you should store it in a globalized variable, convert it into int or float. Then, simply use delete(0, END) to clear what's inside the Entry widget and then use insert() to insert the new value in the Entry.
Like This:
from tkinter import *
var = 0
def fct_temp_plus():
global var
var = float(tekstvak_input_user.get())
var += 1
tekstvak_input_user.delete(0, END)
tekstvak_input_user.insert(0, var)
def fct_temp_min():
global var
var = float(tekstvak_input_user.get())
var -= 1
tekstvak_input_user.delete(0, END)
tekstvak_input_user.insert(0, var)
window = Tk()
window.geometry("800x400") # not *
window.title("TEST")
label = Label(window, text="Temp?")
label.place(x=350, y=175)
temp_plus = Button(window, bd=10, width=10, height=1, text="+", command=fct_temp_plus, font=("Helvetica", 12))
temp_plus.place(x=500, y=150)
temp_min = Button(window, bd=10, width=10, height=1, text="-", font=("Helvetica", 12), command=fct_temp_min)
temp_min.place(x=500, y=200)
tekstvak_input_user = Entry(window, width=10)
tekstvak_input_user.insert(0, 19.0)
tekstvak_input_user.place(x=350, y=200)
window.mainloop()
Note: You should always import tkinter as tk.
Like This:
import tkinter as tk
var = 0
def fct_temp_plus():
global var
var = float(tekstvak_input_user.get())
var += 1
tekstvak_input_user.delete(0, tk.END)
tekstvak_input_user.insert(0, var)
def fct_temp_min():
global var
var = float(tekstvak_input_user.get())
var -= 1
tekstvak_input_user.delete(0, tk.END)
tekstvak_input_user.insert(0, var)
window = tk.Tk()
window.geometry("800x400")
window.title("TEST")
label = tk.Label(window, text="Temp?")
label.place(x=350, y=175)
temp_plus = tk.Button(window, bd=10, width=10, height=1, text="+", command=fct_temp_plus, font=("Helvetica", 12))
temp_plus.place(x=500, y=150)
temp_min = tk.Button(window, bd=10, width=10, height=1, text="-", font=("Helvetica", 12), command=fct_temp_min)
temp_min.place(x=500, y=200)
tekstvak_input_user = tk.Entry(window, width=10)
tekstvak_input_user.insert(0, 19.0)
tekstvak_input_user.place(x=350, y=200)
window.mainloop()

Related

Python progress bar selecting limitation

I'm using Tkinter with a progress bar.
I've got the code below with the "callback" function that adding 50% to my progress bar.
I would like to limit the function to work only once for each OptionMenu selection.
Currently, I can click twice on the first OptionMenu and get to 100% in the progress bar.
Does anyone know what I should change in the "callback" function in order to make it work only once for each OptionMenu? No matter how many times the user has clicked to change its selected value.
from tkinter import *
from tkinter.ttk import Progressbar
root = Tk()
root.title('Input window V1')
root.geometry('600x400')
root.resizable(False, False)
frame = Frame(root, width=600, height=400)
frame.configure(background="gray28")
frame.pack(fill=BOTH, expand=True)
progress = Progressbar(root, orient=HORIZONTAL, length=300, mode='determinate')
progress.place(x=150, y=15)
Budget = {'Flexible', 'Variable', 'Fixed'}
Commitment = {'High', 'Medium', 'Low'}
def callback(*args):
progress["value"] += 50
bottom_header = Label(root, bg="gray28", fg="white", pady=3,
font=("Helvetica", 20, 'underline'), text='Please fill the following attributes:')
bottom_header.place(x=110, y=100)
lbl1 = Label(root, bg="gray28", text='Budget:', fg="cyan2", font=("Helvetica", 14))
lbl1.place(x=120, y=200)
lbl2 = Label(root, bg="gray28", text='Commitment:', fg="cyan2", font=("Helvetica", 14))
lbl2.place(x=120, y=240)
var1 = StringVar(root)
pl1 = OptionMenu(root, var1, *Budget)
pl1.config(width=20, bg="GREEN", fg="white")
pl1.place(x=250, y=200)
var1.trace("w", callback)
var2 = StringVar(root)
pl2 = OptionMenu(root, var2, *Commitment)
pl2.config(width=20, bg="GREEN", fg="white")
pl2.place(x=250, y=240)
var2.trace("w", callback)
global var_dict
var_dict = dict(Budget=var1,
Commitment=var2)
button1 = Button(root, text="Test")
button1.config(width=25, bg="white")
button1.place(x=220, y=320)
root.mainloop()
Thanks in advance!
Try this out:
from tkinter import *
from tkinter.ttk import Progressbar
def callback(*args):
user_input = (var_1.get(), var_2.get()) # Here you can add even more variables
value = 100 - 100/len(user_input)*(user_input.count("")+user_input.count("Select option"))
progress.config(value=value)
root = Tk()
progress = Progressbar(root, orient="horizontal", length=300)
progress.pack()
var_1 = StringVar(root)
var_1.trace("w", callback)
optionmenu_1 = OptionMenu(root, var_1, "Select option", "Option 1", "Option 2")
optionmenu_1.pack()
var_2 = StringVar(root)
var_2.trace("w", callback)
optionmenu_2 = OptionMenu(root, var_2, "Select option", "Option 1", "Option 2")
optionmenu_2.pack()
# You can remove these if you don't like them:
var_1.set("Select option")
var_2.set("Select option")
root.mainloop()
It counts the number of empty OptionMenus and setts the progress bar to the correct percentage.
Keep track of which of the two you have already accounted for, and update only if there was not yet 50% added for this part.
The callback function is changed (and is understandable) and the passing of the callback is changed to a lambda function (which can be confusing if you never used them).
this works for me:
from tkinter import *
from tkinter.ttk import Progressbar
root = Tk()
root.title('Input window V1')
root.geometry('600x400')
root.resizable(False, False)
frame = Frame(root, width=600, height=400)
frame.configure(background="gray28")
frame.pack(fill=BOTH, expand=True)
progress = Progressbar(root, orient=HORIZONTAL, length=300, mode='determinate')
progress.place(x=150, y=15)
Budget = {'Flexible', 'Variable', 'Fixed'}
Commitment = {'High', 'Medium', 'Low'}
budgetset = False
commitmentset = False
def callback(nb):
global budgetset, commitmentset
if nb == 0 and not budgetset:
budgetset = True
progress["value"] += 50
if nb == 1 and not commitmentset:
commitmentset = True
progress["value"] += 50
bottom_header = Label(root, bg="gray28", fg="white", pady=3,
font=("Helvetica", 20, 'underline'), text='Please fill the following attributes:')
bottom_header.place(x=110, y=100)
lbl1 = Label(root, bg="gray28", text='Budget:', fg="cyan2", font=("Helvetica", 14))
lbl1.place(x=120, y=200)
lbl2 = Label(root, bg="gray28", text='Commitment:', fg="cyan2", font=("Helvetica", 14))
lbl2.place(x=120, y=240)
var1 = StringVar(root)
pl1 = OptionMenu(root, var1, *Budget)
pl1.config(width=20, bg="GREEN", fg="white")
pl1.place(x=250, y=200)
var1.trace("w", lambda *_, x=0: callback(x))
var2 = StringVar(root)
pl2 = OptionMenu(root, var2, *Commitment)
pl2.config(width=20, bg="GREEN", fg="white")
pl2.place(x=250, y=240)
var2.trace("w", lambda *_, x=1: callback(x))
global var_dict
var_dict = dict(Budget=var1,
Commitment=var2)
button1 = Button(root, text="Test")
button1.config(width=25, bg="white")
button1.place(x=220, y=320)
root.mainloop()

why am I getting this TypeError: () got an unexpected keyword argument error?

I was trying to add tkinter graphics to a small part of my code for some reason and want the output(calculated sum) on window.How did I make this code working please help!
my code:
import tkinter as tk
from tkinter import *
window = tk.Tk()
window.geometry('400x600')
window.resizable(0, 0)
window.title("HACKER-simple interest setup")
# define entry variables
n1 = StringVar()
n2 = StringVar()
n3 = StringVar()
def simple_interest(*x):
global principal, time
principal = float(principal.get())
time = float(time.get())
interest_rate = float(ir.get())
# simple interest calculating engine
simple_interest(Simple_Interest=principal * (interest_rate / 100) * time)
Output = Text(window, width=25, bg="light cyan")
Output.grid(column=0, row=4)
Output.place(x=150, y=300)
Output.insert(END, "Simple_Interest:", simple_interest)
lbl = Label(window, text="Principal:", font=("Aerial Bold Italic", 15))
lbl.grid(column=0, row=4)
lbl.place(x=45, y=125)
lbl = Label(window, text="Time:", font=("Aerial Bold Italic", 15))
lbl.grid(column=0, row=4)
lbl.place(x=70, y=150)
lbl = Label(window, text="Interest rate:", font=("Aerial Bold Italic", 15))
lbl.grid(column=0, row=4)
lbl.place(x=12, y=170)
principal = tk.Entry(window, textvariable=n1, width=40)
principal.grid(column=0, row=4)
principal.place(x=130, y=130)
time = tk.Entry(window, textvariable=n2, width=40)
time.grid(column=0, row=4)
time.place(x=130, y=150)
ir = tk.Entry(window, textvariable=n3, width=40)
ir.grid(column=0, row=4)
ir.place(x=130, y=170)
btn = Button(window, text="Calculate", bg="red", fg="white", command=simple_interest)
btn.grid(column=0, row=5)
btn.place(x=220, y=200)
window.mainloop()
getting error:
C:\Users\Anmol\AppData\Local\Programs\Python\Python38\python.exe "D:/Downloads/si test.py"
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Anmol\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "D:/Downloads/si test.py", line 22, in simple_interest
simple_interest(Simple_Interest=principal * (interest_rate / 100) * time)
TypeError: simple_interest() got an unexpected keyword argument 'Simple_Interest'
I think you can use Simple_Interest=principal * (interest_rate / 100) * time at line 22.
And you should use the "if" statement in line 17-19
import tkinter as tk
from tkinter import *
window = tk.Tk()
window.geometry('400x600')
window.resizable(0, 0)
window.title("HACKER-simple interest setup")
# define entry variables
n1 = StringVar()
n2 = StringVar()
n3 = StringVar()
def simple_interest(*x):
global principal, time
principal = float(principal.get() if not isinstance(principal,float) else principal)
time = float(time.get()) if not isinstance(time,float) else time
interest_rate = float(ir.get()) if not isinstance(ir,float) else ir
# simple interest calculating engine
Simple_Interest=principal * (interest_rate / 100) * time
Output = Text(window, width=25, bg="light cyan")
Output.grid(column=0, row=4)
Output.place(x=150, y=300)
Output.insert(END, "Simple_Interest:\n"+str(Simple_Interest))
lbl = Label(window, text="Principal:", font=("Aerial Bold Italic", 15))
lbl.grid(column=0, row=4)
lbl.place(x=45, y=125)
lbl = Label(window, text="Time:", font=("Aerial Bold Italic", 15))
lbl.grid(column=0, row=4)
lbl.place(x=70, y=150)
lbl = Label(window, text="Interest rate:", font=("Aerial Bold Italic", 15))
lbl.grid(column=0, row=4)
lbl.place(x=12, y=170)
principal = tk.Entry(window, textvariable=n1, width=40)
principal.grid(column=0, row=4)
principal.place(x=130, y=130)
time = tk.Entry(window, textvariable=n2, width=40)
time.grid(column=0, row=4)
time.place(x=130, y=150)
ir = tk.Entry(window, textvariable=n3, width=40)
ir.grid(column=0, row=4)
ir.place(x=130, y=170)
btn = Button(window, text="Calculate", bg="red", fg="white", command=simple_interest)
btn.grid(column=0, row=5)
btn.place(x=220, y=200)
window.mainloop()
It was worked!
change line 22 simple_interest(Simple_Interest=principal * (interest_rate / 100) * time)
to simple_interest=principal * (interest_rate / 100) * time
change line 27 Output.insert(END, "Simple_Interest:", simple_interest) to Output.insert(END, "Simple_Interest:" + str(simple_interest))
How was I able to solve it?
I assigned the simple interest to variable simple interest
and for the output, it was just printing 'simple interest' as a string so I replaced it with out result

Parameters passed to a function does not works as intended

When the "view" button is pressed, it should trigger the function solution(i) such that label should be displayed in the new window. The problem is that the window opens and the previous label is packed but the label which gets it's text from "i" does not gets packed, Is there any issue in passing the parameter.
Any help is appreciated.
root = Tk()
root.config(background = "#303939")
root.state('zoomed')
def pre():
with open("DoubtSolution.txt","r+") as f:
dousol = f.read()
dousol_lst = dousol.split("`")
k = 0
window = Tk()
window.config(background = "#303939")
window.state('zoomed')
predoubt = Label(window,
text="Previous Doubts",
fg="Cyan",
bg="#303939",
font="Helvetica 50 bold"
).grid(row=0, column=1)
def solution(text):
print(text)
window1 = Tk()
window1.config(background="#303939")
window1.state('zoomed')
sol = Label(window1,
text=text[:text.find("~")],
font=font.Font(size=20),
bg="#303939",
fg="Cyan")
sol.pack()
window1.mainloop()
for i in dousol_lst:
if i[-5:] == admno:
doubt = Label(window, text=i[i.find("]]")+2:i.find("}}}}")], font=font.Font(size=20), bg="#303939",
fg="Cyan")
doubt.grid(row=2+k, column=1, pady=10)
view = Button(
master=window,
text="View", font=font.Font(size=15, family="Helvetica"),
activebackground="White",
bg="Teal",
bd=0.8,
fg="White",
command = lambda k = k:solution(i)
)
view.grid(row=2+k, column=2, padx=20)
k=k+1
window.mainloop()
previous = Button(
master=root,
text="Previous Doubts", font="Helvetica 22 bold",
activebackground="White",
bg="Teal",
bd=0.8,
fg="White",
command = pre
).grid(row=4, column=3, padx=20)
root.mainloop()

Tkinter get numbers from value

I wrote the code below for a program that calculates the 'delta' that we use for second degree equations. I already wrote a calculator, which gets the numeric value from the entry like this: firstnum=entry.get().
However, when I tried to do same on the delta, I get the error:
AttributeError: 'NoneType' object has no attribute 'get'
from tkinter import
from tkinter.font import Font
import sys*
# window interface
r = Tk()
r.geometry("300x500")
r.configure(bg="#414d61")
# commands
def clear():
r.quit()
def delta():
ax = entry_ax.get()
bx = entry_bx.get()
c = entry_c.get()
result = bx * bx - 4 * ax * c
entry_delta.insert(0, result)
# text interface
text = Text(r)
My_font = Font(family="Arial Rounded MT Bold", size=12)
# labels and frames
label_top = Label(r, bg="#414d61", text="x² + (", font=My_font).place(x=80, y=200)
label_top2 = Label(r, bg="#414d61", text=" x) +", font=My_font).place(x=140, y=200)
label_top3 = Label(r, bg="#414d61", text=" =0", font=My_font).place(x=200, y=200)
entry_ax = Entry(r, bg="white", width=2).place(x=60, y=202)
entry_bx = Entry(r, bg="white", width=2).place(x=138, y=202)
entry_c = Entry(r, bg="white", width=2).place(x=198, y=202)
entry_delta = Entry(r, bg="white", width=20).place(x=85, y=350)
# Buttons
b1 = Button(r, bg="#414d61", text="Calculate Delta", font=My_font, command=delta, height=1, width=20)
b1.place(x=40, y=300)
b2 = Button(r, bg="#414d61", text="Exit", font=My_font, command=clear, height=1, width=20)
b2.place(x=40, y=400)
# entries
entry = Label(r, bg="#414d61", text="Delta Calculator (basic gui version)", font=My_font, width=30)
entry.place(x=5, y=100)
r.mainloop()
Ok this is a very common mistake. When you create your Entry you do this:
variable = Entry(...).place(...)
That creates the entry then immediately calls its .place method. It stores whatever .place returns (always None) to variable. What you want to do is this:
variable = tk.Entry(...)
variable.place(...)

How to shoving tkinter function result in a new window?

I am trying to make a staffing calculator using GUI tkinter in python I expect to get the function calculation results once I fill all entries and click on calculate button in a new window (master) based on the entry but unfortunately I got an empty label in the new window also I am not reeving any error to fix, would you please help me?, here is my code and screen shot:
from tkinter import *
root = Tk()
root.title("Workload Staffing Calculator")
#Header
headerlab = Label(root, text="Please fill the below form and click calculate to get the required staff.").grid(row=0,columnspan=2,pady=20,padx=20)
#Inputs names
vollabel = Label(root, text="Volumes").grid(padx=0,pady=10)
ahtlabel = Label(root, text="AHT (sec.)").grid(padx=0, pady=10)
Occlabel = Label(root, text="Occupancy (%)").grid(padx=0, pady=10)
Shrinklabel = Label(root, text="Shrinkage (%)").grid(padx=0, pady=10)
weekendlabel = Label(root, text="Days Off").grid(padx=0, pady=10)
Shiftlabel = Label(root, text="Shift Duration (h)").grid(padx=0, pady=10)
#Entry inptus
volentry = Entry(root, width=10, borderwidth=3)
ahtentry = Entry(root, width=10, borderwidth=3)
occentry = Entry(root, width=10, borderwidth=3)
shrinkentry = Entry(root, width=10, borderwidth=3)
weekendentry = Entry(root, width=10, borderwidth=3)
shiftentry = Entry(root, width=10, borderwidth=3)
#shoving inputs on screen
volentry.grid(row=1, column=1, padx=20)
ahtentry.grid(row=2, column=1, padx=20)
occentry.grid(row=3, column=1, padx=20)
shrinkentry.grid(row=4, column=1, padx=20)
weekendentry.grid(row=5, column=1, padx=20)
shiftentry.grid(row=6, column=1, padx=20)
#Calculate Fuction
def calstaff() :
v = volentry.get()
a = ahtentry.get()
o = occentry.get()
s = shrinkentry.get()
w = weekendentry.get()
sh = shiftentry.get()
required = (int(v) * int(a)) / (int(sh) * 3600)
total = required * (7 / (7 - int(w))) * (1 + float(s))
newwindow = Tk()
newwindow.title("The required is: ")
result = Label(newwindow, textvariable=total).pack()
return result
#calculate button
calculate = Button(root, text="Calculate", command=calstaff)
calculate.grid(padx=20,pady=10)
root.mainloop()
It is not recommended to use Tk() more than once as it can interrupt the flow of the main loop. To create another window you should try using Toplevel()
Secondly, Instead of textvariable use text
Refer to the code below:
.
..
def calstaff() :
v = volentry.get()
a = ahtentry.get()
o = occentry.get()
s = shrinkentry.get()
w = weekendentry.get()
sh = shiftentry.get()
required = (int(v) * int(a)) / (int(sh) * 3600)
total = required * (7 / (7 - int(w))) * (1 + float(s))
newwindow = Toplevel() #TOPLEVEL() USED
newwindow.title("The required is: ")
result = Label(newwindow, text=total) #text instead of textvariable
result.pack()
newwindow.mainloop() #mainloop for newwindow
..

Categories