Reputation: 113
I'm a newbie to Python's Tkinter, and I'd like to create a program running on it. However, my code doesn't work correctly.
from tkinter import *
def conv1(self):
gbp0 = 174000000
galleons0 = 34000872
sickles0 = 14
knuts0 = 7
galleons1 = float(galleons0 + sickles0 / 17 + knuts0 / 29 / 17)
fracture = float(gbp0 / galleons1)
convert1 = Toplevel(root)
convert1.title("Pounds Sterling (GBP) to Galleons, Sickles and Knuts Converter")
label1_1 = Label(convert1, text="Type the amount of money in GBP that you would like to convert to Galleons, Sickles and Knuts and press Enter.")
label1_2 = Label(convert1, text="1 Galleon = 5.12 GBP")
label1_3 = Label(convert1, text='GBP:')
label1_1.pack()
label1_2.pack()
label1_3.pack()
usergbpvar = DoubleVar()
usergbp = Entry(convert1, textvariable=usergbpvar)
usergbp.pack()
a = float(usergbpvar.get() / fracture)
galleons = int(a // 1)
a = (a % 1) * 17
sickles = int(a // 1)
a = (a % 1) * 29
if (a % 1) == 0.5:
knuts = int(round(a, 0))
knuts += 1
else:
knuts = int(round(a, 0))
galleons, sickles, knuts = str(galleons), str(sickles), str(knuts)
label1_4 = Label(convert1, text=galleons)
label1_5 = Label(convert1, text=sickles)
label1_6 = Label(convert1, text=knuts)
label1_4.pack()
label1_5.pack()
label1_6.pack()
convert1.mainloop()
root = Tk()
btn1 = Button(root, text='GBP to Galleons, Sickles and Knuts', bg='#555', fg='#ccc', font='16')
btn1.pack()
btn1.bind('<Button-1>', conv1)
root.mainloop()
It's supposed to calculate three numbers out of the entered one, and to show them on the screen. However, when I run the program, after pressing the button I see that all the numbers are already there and they are 0. After I enter my number, nothing is changed.
Could you please tell me where the issue in my code is?
Upvotes: 1
Views: 206
Reputation: 492
Problem/Question 1:
when I run the program, after pressing the button I see that all the numbers are already there and they are 0.
When you call
label1_4=Label(convert1, text=galleons)
label1_4.pack()
this tells tkinter to display the label immediately with the given value e.g. galleons for label1_4, which is 0 (same for the other labels). This isn't a problem and is expected as the value of the entry box is 0 to begin with.
Problem/Question 2:
After I enter my number, nothing is changed.
You don't actually tell the program to ever update the value of the labels. As TornaxO7 said, you need to bind the enter (return) key to call a function usergbp.bind("<Return>", calculation_function_here)
I have edited your code to give an object oriented approach. I would suggest exploring this approach as you progress and perhaps want multiple windows. Best way to structure a tkinter application?
from tkinter import *
class gui_window:
def __init__(self, master):
# setup gui
self.master = master
self.master.wait_visibility() # attempt to fix traceback error, see Problem/question 3 below
self.master.grab_set() # stops button1 creating another gui_window instance
self.master.title('Pounds Sterling (GBP) to Galleons, Sickles and Knuts Converter')
self.label1_1=Label(master, text="Type the amount of money in GBP that you would like to convert to Galleons, Sickles and Knuts and press Enter.")
self.label1_1.pack()
self.label1_2=Label(master, text="1 Galleon = 5.12 GBP")
self.label1_2.pack()
self.label1_3=Label(master, text='GBP:')
self.label1_3.pack()
self.usergbpvar=DoubleVar()
self.usergbp=Entry(master, textvariable=self.usergbpvar)
self.usergbp.bind("<Return>", self.calculate) # when user presses enter call the conversion function
self.usergbp.pack()
label1_4_1 = Label(self.master, text = 'Galleons:').pack(anchor = 'w')
self.label1_4=Label(self.master, text='0', anchor = 'e')
self.label1_4.pack()
label1_5_1 = Label(self.master, text = 'Sickles:').pack(anchor = 'w')
self.label1_5=Label(self.master, text='0', anchor = 'e')
self.label1_5.pack()
label1_6_1 = Label(self.master, text = 'Knuts:').pack(anchor = 'w')
self.label1_6=Label(self.master, text='0')
self.label1_6.pack()
self.gbp0=174000000
self.galleons0=34000872
self.sickles0=14
self.knuts0=7
self.galleons1=float(self.galleons0+self.sickles0/17+self.knuts0/29/17)
self.fracture=float(self.gbp0/self.galleons1)
def calculate(self, event):
# do calculation
a=float(self.usergbpvar.get()/self.fracture)
galleons=int(a//1)
a=a%1
a=a*17
sickles=int(a//1)
a=a%1
a=a*29
if a%1==0.5:
knuts=int(round(a, 0))
knuts=knuts+1
else:
knuts=int(round(a, 0))
galleons=str(galleons)
sickles=str(sickles)
knuts=str(knuts)
# update the labels to reflect the calculation
self.label1_4.config(text=galleons)
self.label1_5.config(text=sickles)
self.label1_6.config(text=knuts)
def create_gui(self):
# create a gui_window Toplevel instance
convert1=Toplevel()
gui_window(convert1)
root=Tk()
btn1=Button(root, text='GBP to Galleons, Sickles and Knuts', bg='#555', fg='#ccc', font='16')
btn1.pack()
btn1.bind('<Button-1>', create_gui) # call function to make next window
root.mainloop()
Problem/Question 3 from comments:
I believe the error: tkinter.TclError: grab failed: window not viewable
is dependant on your OS. I am unable to reproduce the error on Mac OS but adding self.master.wait_visibility()
(added into my code) may fix this:
python tkinter treeview not allowing modal window with direct binding like on_rightclick
Upvotes: 3
Reputation: 1299
I guess that you forgot to bind the Return
-key.
You should add convert1.bind("<Return>", *your function*)
in your method.
"your function" is the function which changes the numbers.
Upvotes: 1