简体   繁体   中英

What is the problem with my code run on Tkinter?

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?

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 eg 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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM