Related
I've built a time conversion widget, the problems I am facing is with the functions I am assigning to specific variables. I would like to work so that when a number is entered in one EntryBox, the other update immediately.
quick outline, with the functions in the code below I am trying to attain the value entered in one Entry, and then convert that value twice, to produce two more values which are then assigned to the relevant variable.
EDIT: I have managed to get one of the functions working, part in thanks to Sujay for point out the *args error. I have now updated the code below to reflect where I am now. The functions appear to work as desire, except for the instance where only entering a value on the HOUR Entry delivers a value in the other two Entries. Entering a value in the Second or Minute Entry yields nothing.
Again any help or guidance is appreciated.
from tkinter import *
from tkinter.ttk import*
#Global Variables
root = Tk()
Second = DoubleVar()
Minute = DoubleVar()
Hour = DoubleVar()
#GUI
class GUI:
def __init__(self, master):
self.self = self
self.master = master
master.title('Time Converter')
master.geometry('+600+300')
master.label1 = Label(root, text = 'Second').grid(column=0, row=0)
master.entry1 = Entry(root, textvariable=Second).grid(pady=5, padx=20, column=0, row=1)
master.label2 = Label(root, text= ' Minute').grid(column=1, row=0)
master.entry2 = Entry(root, textvariable=Minute).grid(pady=5, padx=20, column=1, row=1)
master.label3 = Label(root, text= ' Hour').grid(column=2, row=0)
master.entry3 = Entry(root, textvariable=Hour).grid(pady=5, padx=20, column=2, row=1)
UpdateInProgress = False
#Conversion Functions
def SecondInput(*args):
GUI.UpdateInProgress
if GUI.UpdateInProgress: return
try:
Second.get()
except ValueError:
return
NewMinute = (Second.get()/60)
NewHour = (Second.get()/3600)
GUI.UpdateInProgress = True
Minute.set(NewMinute)
Hour.set(NewHour)
GUI.UpdateInProgress = False
def MinuteInput(*args):
GUI.UpdateInProgress
if GUI.UpdateInProgress: return
try:
Minute.get()
except ValueError:
return
NewSecond = (Minute.get()*60)
NewHour = (Minute.get()*0.01667)
GUI.UpdateInProgress = True
Second.set(NewSecond)
Hour.set(NewHour)
GUI.UpdateInProgress = False
def HourInput(*args):
GUI.UpdateInProgress
if GUI.UpdateInProgress: return
try:
Hour.get()
except ValueError:
return
NewMinute = (Hour.get()*60)
NewSecond = (Hour.get()*3600)
GUI.UpdateInProgress = True
Minute.set(NewMinute)
Second.set(NewSecond)
GUI.UpdateInProgress = False
#Assigning functions to variables
Second.trace("w",MinuteInput)
Minute.trace("w",SecondInput)
Hour.trace("w",HourInput)
#Mainloop
def main():
GUI(root)
root.mainloop()
main()
Found this issue
Assigned the functions to the wrong variables.
sighs
Thanks to Sujay for commenting, here's where the issue was:
Second.trace("w",MinuteInput)
Minute.trace("w",SecondInput)
Hour.trace("w",HourInput)
should have been
Second.trace("w",SecondInput)
Minute.trace("w",MinuteInput)
Hour.trace("w",HourInput)
Can someone help me, Im trying to make a banking program and when i try to login and enter the correct details, it still says "notok". I put in some values for testing purposes and it just wont work and it would always print notok. Please help
import tkinter as tk
from tkinter import messagebox
import random
def checklog(ac,pin):
if (ac==1) and (pin==2):
print("ok")
else:
print("notok")
def exitwin(master):
master.destroy()
def acc_no(master):
acc_no.acc = random.randrange(1000000000,9999999999)
messagebox.showinfo("Account Number", acc_no.acc)
return
def openac():
op = tk.Tk()
op.title("Open a account")
op.minsize(500,500)
op.configure(bg='gray90')
l1 = tk.Label(op, text="Full Name")
l1.grid(row=0, column=2)
openac.name = tk.Entry(op)
openac.name.grid(row=0, column=3)
l2 = tk.Label(op, text="Enter Starting Deposit")
l2.grid(row=1, column=2)
openac.fun = tk.Entry(op)
openac.fun.grid(row=1, column=3)
l3 = tk.Label(op, text="Enter your pin")
l3.grid(row=2, column=2)
openac.pin = tk.Entry(op, show="*")
openac.pin.grid(row=2, column=3)
sub = tk.Button(op, text="Submit", command=lambda: [acc_no(op), login(), exitwin(op)])
sub.grid(row=3, column=1)
op.bind("<Return>", lambda x:[dep(op, e1.get(),e2.get(), e3.get()), acc_no(op), login(op, e1.get(), e2.get(), e3.get()), exitwin(op)])
return
def login():
log = tk.Tk()
log.title("Login")
log.minsize(500,500)
l1 = tk.Label(log, text="Enter your account number")
l1.grid(row=0, column=0)
e1 = tk.Entry(log)
e1.grid(row=0, column=1)
l2 = tk.Label(log, text="Enter your pin")
l2.grid(row=1, column=0)
e2 = tk.Entry(log)
e2.grid(row=1, column=1)
sub = tk.Button(log, text="Sumbit", command=lambda: checklog(e1.get(), e2.get()))
sub.grid(row=1, column=2)
return
log.mainloop()
def dep(master, name, fund, pin):
x=0
def draw():
x=0
def mainmenu():
mm = tk.Tk()
mm.title("Bank")
mm.minsize(400,400)
mm.configure(bg='gray70')
l1 = tk.Label(mm, text="HELLO")
l1.config(font=("Courier", "25"))
l1.grid(row=0)
b1 = tk.Button(mm, text="Sign Up", command=openac)
b1.grid(row=2)
b2 = tk.Button(mm, text="Log In", command=lambda: login(mm))
b2.grid(row=3)
mm.mainloop()
mainmenu()
You're checking if the .get()'s of your text boxes are equal to an integer, but you have not converted them into an integer, they are a string by default.
def checklog(ac, pin):
if ac == "1" and pin == "2":
print("ok")
else:
print("not ok")
Best practice dictates that you convert the value to an integer yourself and throw an error when it cannot be converted. Something that tells the user their account number or pin failed validation as it is not a number.
The values that you pass to checklog come from calling .get on a tk.Entry, which produces a string (it must do this, because you could type whatever text you like, not just ones that look like numbers). The comparison ac==1 fails because ac is a string. You must convert the value yourself, and handle the case when a non-number is typed.
This is not really a Tkinter question; it's the same problem that beginners have all the time with input().
I am trying to add a reset button but I can't seem to get it to work. I created a main in order to refer back to it when the button is pressed but no luck. Any ideas?
import sys
from tkinter import *
import math
def main():
def closeWin():
myGui.destroy() #Close Window Function
def kiloFunc():
myText = kiloMent.get() #Kilometers to Miles Fuction
convert = 0.62
miles = myText * convert
finalKilo = Label(text = miles,fg='red',justify='center').place(x=200,y=80)
def mileFunc():
myText2 = mileMent.get() #Miles to Kilometers Function
convertTwo = myText2 // 0.62
finalMile = Label(text = convertTwo, fg = 'red',justify='center').place(x=200,y=170)
myGui = Tk()
kiloMent = IntVar()
mileMent = IntVar()
myGui.title("Distance Converter")
myGui.geometry("450x200+500+200")
myLabel = Label(text="Welcome! Please enter your value then choose your option:",fg="blue",justify='center')
myLabel.pack()
kiloEntry = Entry(myGui, textvariable = kiloMent,justify='center').pack()
kilo2milesButton = Button(text = "Kilometers to Miles!", command = kiloFunc).pack()
mileEntry = Entry(myGui, textvariable = mileMent,justify='center').place(x=130,y=105)
miles2kiloButton = Button(text = "Miles to Kilometers!", command = mileFunc).place(x=150,y=135)
reset = Button(text = "Reset Values!", command = main).place(x=10,y=165)
quit = Button(text="Quit", command = closeWin).place(x=385,y=165)
myGui.mainloop()
main()
By calling main() again, you are simply creating another instance of the GUI. What you should do instead is (if I understand correctly), reset the values of the currently existing GUI. You can use the set() method of the GUI objects.
Does
def reset_values():
kiloMent.set(0)
mileMent.set(0)
reset = Button(text="Reset Values!", command=reset_values).place(x=10, y=165)
do the trick?
Looking at your code more thoroughly, however, there are some other problems there, as well. To start with, I would suggest not creating a Label everytime the user tries to convert a value.
This code should work:
from tkinter import *
def main():
def closeWin():
myGui.destroy() # Close Window Function
def kiloFunc():
finalKilo.set(kiloMent.get() * 0.62) # Kilometers to Miles Fuction
def mileFunc():
finalMile.set(mileMent.get() // 0.62) # Miles to Kilometers Function
def clearFunc():
kiloMent.set("0")
mileMent.set("0")
finalKilo.set("")
finalMile.set("")
myGui = Tk()
kiloMent = IntVar()
mileMent = IntVar()
finalKilo = StringVar()
finalMile = StringVar()
myGui.title("Distance Converter")
myGui.geometry("450x200+500+200")
myLabel = Label(text="Welcome! Please enter your value then choose your option:", fg="blue", justify='center')
myLabel.pack()
kiloEntry = Entry(myGui, textvariable=kiloMent, justify='center')
kiloEntry.pack()
kilo2milesButton = Button(text="Kilometers to Miles!", command=kiloFunc)
kilo2milesButton.pack()
mileEntry = Entry(myGui, textvariable=mileMent, justify='center')
mileEntry.place(x=130, y=105)
miles2kiloButton = Button(text="Miles to Kilometers!", command=mileFunc)
miles2kiloButton.place(x=150, y=135)
kiloLabel = Label(textvariable=finalKilo, fg='red', justify='center')
kiloLabel.place(x=200, y=80)
mileLabel = Label(textvariable=finalMile, fg='red', justify='center')
mileLabel.place(x=200, y=170)
reset = Button(text="Reset Values!", command=clearFunc)
reset.place(x=10, y=165)
quit = Button(text="Quit", command=closeWin)
quit.place(x=385, y=165)
myGui.mainloop()
main()
A few notes about your original code besides the ones that Chuck mentioned:
The math and sys imports were unused.
You were setting variables equal to widget.pack() and widget.place(), which are functions that return None.
[Python 2.7] Hello. I'm working on a simple Tkinter calculator program, but can't seem to get the label to display any text after I push one of the buttons. Here is the code I'm using, some of the button functions are unfinished until I can get the label itself working:
from Tkinter import *
import ttk
"""Calculator"""
#Variables
Entered = ""
#Button Functions
def Natural_Log():
pass
def Exp():
Entered = "^"
def Sin():
pass
def Cos():
pass
def Tan():
pass
def LeftParentheses():
Entered = Entered + "("
def RightParentheses():
Entered = Entered + ")"
def Log():
pass
def XSquared():
Entered = Entered + "**2"
def InvX():
Entered = Entered + "**-1"
def Seven():
Entered = Entered + "7"
def Eight():
Entered = Entered + "8"
def Nine():
Entered = Entered + "9"
def DEL():
Entered = Entered[:1]
def AC():
Entered = ""
def Four():
Entered = Entered + "4"
def Five():
Entered = Entered + "5"
def Six():
Entered = Entered + "6"
def Mult():
Entered = Entered + "*"
def Div():
Entered = Entered + "/"
def One():
Entered = Entered + "1"
def Two():
Entered = Entered + "2"
def Three():
Entered = Entered + "3"
def Plus():
Entered = Entered + "+"
def Minus():
Entered = Entered + "-"
def Zero():
Entered = Entered + "0"
def Decimal():
Entered = Entered + "."
def Ex():
pass
def neg():
pass
def EXE():
pass
#Main Window Setup:
#Root setup
root = Tk()
root.title("Generic Calculator")
#Parent frame setup
mainframe = ttk.Frame(root,padding="8")
mainframe.grid(column=0,row=0,sticky=(N,S,E,W))
mainframe.columnconfigure(0,weight=1)
mainframe.rowconfigure(0,weight=1)
#Button setup
ttk.Button(mainframe,text="ln",command=Natural_Log).grid(column=1,row=2,sticky=W)
ttk.Button(mainframe,text="^",command=Exp).grid(column=2,row=2,sticky=W)
ttk.Button(mainframe,text="sin",command=Sin).grid(column=3,row=2,sticky=W)
ttk.Button(mainframe,text="cos",command=Cos).grid(column=4,row=2,sticky=W)
ttk.Button(mainframe,text="tan",command=Tan).grid(column=5,row=2,sticky=W)
ttk.Button(mainframe,text="(",command=LeftParentheses).grid(column=1,row=3,sticky=W)
ttk.Button(mainframe,text=")",command=RightParentheses).grid(column=2,row=3,sticky=W)
ttk.Button(mainframe,text="log",command=Log).grid(column=3,row=3,sticky=W)
ttk.Button(mainframe,text="x^2",command=XSquared).grid(column=4,row=3,sticky=W)
ttk.Button(mainframe,text="x^-1",command=InvX).grid(column=5,row=3,sticky=W)
ttk.Button(mainframe,text="7",command=Seven).grid(column=1,row=4,sticky=W)
ttk.Button(mainframe,text="8",command=Eight).grid(column=2,row=4,sticky=W)
ttk.Button(mainframe,text="9",command=Nine).grid(column=3,row=4,sticky=W)
ttk.Button(mainframe,text="DEL",command=DEL).grid(column=4,row=4,sticky=W)
ttk.Button(mainframe,text="AC",command=AC).grid(column=5,row=4,sticky=W)
ttk.Button(mainframe,text="4",command=Four).grid(column=1,row=5,sticky=W)
ttk.Button(mainframe,text="5",command=Five).grid(column=2,row=5,sticky=W)
ttk.Button(mainframe,text="6",command=Six).grid(column=3,row=5,sticky=W)
ttk.Button(mainframe,text="*",command=Mult).grid(column=4,row=5,sticky=W)
ttk.Button(mainframe,text="/",command=Div).grid(column=5,row=5,sticky=W)
ttk.Button(mainframe,text="1",command=One).grid(column=1,row=6,sticky=W)
ttk.Button(mainframe,text="2",command=Two).grid(column=2,row=6,sticky=W)
ttk.Button(mainframe,text="3",command=Three).grid(column=3,row=6,sticky=W)
ttk.Button(mainframe,text="+",command=Plus).grid(column=4,row=6,sticky=W)
ttk.Button(mainframe,text="-",command=Minus).grid(column=5,row=6,sticky=W)
ttk.Button(mainframe,text="0",command=Zero).grid(column=1,row=7,sticky=W)
ttk.Button(mainframe,text=".",command=Decimal).grid(column=2,row=7,sticky=W)
ttk.Button(mainframe,text="EXP",command=Ex).grid(column=3,row=7,sticky=W)
ttk.Button(mainframe,text="(-)",command=neg).grid(column=4,row=7,sticky=W)
ttk.Button(mainframe,text="EXE",command=EXE).grid(column=5,row=7,sticky=W)
#Label Setup:
EnteredSetup = StringVar()
ttk.Label(mainframe,textvariable=EnteredSetup).grid(column=1,row=1,columnspan=5)
EnteredSetup.set(Entered)
root.mainloop()
I believe there is a misunderstanding on how StringVar works. The line
EnteredSetup.set(Entered)
does not create some form of link between EnteredSetup and Entered, modifying Entered does not issue updates in EnteredSetup. Your code can be improved a lot too, and you should post something that is only long enough to describe the problem. Said that, consider this reduced version already fixed (note that it could be much smaller):
from Tkinter import Tk, StringVar
import ttk
class Calculator:
def __init__(self, state):
self.state = state
def ac(self):
self.state.set('')
def state_num(self, num):
self.state.set('%s%d' % (self.state.get(), num))
#Main Window Setup:
#Root setup
root = Tk()
root.title("Generic Calculator")
EnteredSetup = StringVar('')
calc = Calculator(EnteredSetup)
#Parent frame setup
mainframe = ttk.Frame(root, padding="8")
mainframe.grid(column=0, row=0)
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
#Button setup
ttk.Button(mainframe, text="AC", command=calc.ac).grid(
column=5, row=4)
ttk.Button(mainframe, text="1", command=lambda: calc.state_num(1)).grid(
column=1, row=6)
ttk.Button(mainframe, text="0", command=lambda: calc.state_num(0)).grid(
column=1, row=7)
#Label Setup:
ttk.Label(mainframe, textvariable=EnteredSetup).grid(
column=1,row=1,columnspan=5)
root.mainloop()
I hope this guides you in the right direction for further adjusting your calculator.
I am learning python and am having trouble getting this program to work correctly.
from Tkinter import*
import time
import tkMessageBox
import random
def Questions():
number1 = random.randrange(1,25,1)
number2 = random.randrange(1,50,2)
answer = number1 + number2
prompt = ("Add " + str(number1) + " and " + str(number2))
label1 = Label(root, text=prompt, width=len(prompt), bg='yellow')
label1.pack()
return answer
def start():
global count_flag
Questions()
count_flag = True
count = 0.0
while True:
if count_flag == False:
break
# put the count value into the label
label['text'] = str(count)
# wait for 0.1 seconds
time.sleep(0.1)
# needed with time.sleep()
root.update()
# increase count
count += 0.1
def Submit(answer, entryWidget):
""" Display the Entry text value. """
global count_flag
count_flag = False
print answer
if entryWidget.get().strip() == "":
tkMessageBox.showerror("Tkinter Entry Widget", "Please enter a number.")
if int(answer) != entryWidget.get().strip():
tkMessageBox.showinfo("Answer", "INCORRECT!")
else:
tkMessageBox.showinfo("Answer", "CORRECT!")
# create a Tkinter window
root = Tk()
root.title("Math Quiz")
root["padx"] = 40
root["pady"] = 20
# Create a text frame to hold the text Label and the Entry widget
textFrame = Frame(root)
#Create a Label in textFrame
entryLabel = Label(textFrame)
entryLabel["text"] = "Answer:"
entryLabel.pack(side=LEFT)
# Create an Entry Widget in textFrame
entryWidget = Entry(textFrame)
entryWidget["width"] = 50
entryWidget.pack(side=LEFT)
textFrame.pack()
#directions
directions = ('Click start to begin. You will be asked a series of questions like the one below.')
instructions = Label(root, text=directions, width=len(directions), bg='orange')
instructions.pack()
# this will be a global flag
count_flag = True
answer = Questions()
Sub = lambda: Submit(answer, entryWidget)
# create needed widgets
label = Label(root, text='0.0')
btn_submit = Button(root, text="Submit", command = Sub)
btn_start = Button(root, text="Start", command = start)
btn_submit.pack()
btn_start.pack()
label.pack()
# start the event loop
root.mainloop()
It just says "INCORRECT!" every time I push submit regardless of what I enter into the text box. Any suggestions would be appreciated. Thanks, Scott
Left side is an integer, right side is a string, so it's always False:
int(answer) != entryWidget.get().strip()
You can try:
int(answer) != int(entryWidget.get().strip())