Question

I just started using Tkinter and so far haven't had too many problems. The main issue I am having is that I am supposed to use tk__init__(self) in the program, which I have and it calculates everything fine. However when I run the program, I'm getting two pop up boxes and not just 1. I am also trying to stretch the main box so that it shows the title completely. Here is my code:

from Tkinter import *

class App(Tk):
    def __init__(self):
        self.root = Tk()
        self.root.title("BMI Calculator")
        Tk.__init__(self)


        # Sets a label and entry field into the window for weight, height in
        # feet, and height in inches
        self.label = Label(self.root, text="Enter your weight in pounds.").pack()
        self.lbs = StringVar()
        Entry(self.root, textvariable=self.lbs).pack()

        self.label = Label(self.root, text="Enter your height in feet.").pack()
        self.feet = StringVar()
        Entry(self.root, textvariable=self.feet).pack()

        self.label = Label(self.root, text="Enter your height in inches.").pack()
        self.inches = StringVar()
        Entry(self.root, textvariable=self.inches).pack()

        # Sets a button and label to click and calculate BMI
        self.buttontext = StringVar()
        Button(self.root, textvariable=self.buttontext, command=self.calculate).pack()
        self.buttontext.set("Calculate")

        # Sets bmi_num to a StringVar so that when it is changed, the label will
        # update
        self.bmi_num = StringVar()
        Label(self.root, textvariable=self.bmi_num).pack()

        # Same thing here
        self.bmi_text = StringVar()
        Label(self.root, textvariable=self.bmi_text).pack()

        self.root.mainloop()

    def calculate(self):
        # Retrieves all necessary information to calculate BMI
        weight = float(self.lbs.get())
        feet = float(self.feet.get())
        inches = float(self.inches.get())
        height = (feet*12)+inches
        bmi = float((weight*703)/(height**2))
        # Updates the status label
        self.bmi_num.set("Your BMI is %.2f" % bmi)
        if bmi < 18.5:
            self.bmi_text.set("You are underweight")
        if 18.5 <= bmi < 25:
            self.bmi_text.set("You are normal")
        if 25 <= bmi < 30:
            self.bmi_text.set("You are overweight")
        if 30<= bmi > 30:
            self.bmi_text.set("You are obese")

App()

Any suggestions as to better write this or just fix this issues would be great. Thanks.

Was it helpful?

Solution

It seems like you're confusing inheritance and encapsulation here. Your App class is inheriting from Tk, which means it IS a Tk. However, you're also encapsulating a Tk object inside App and assigning it to self.root. So you've got App, which is a subclass of Tk, encapsulating App.root, which is also a Tk.

You're actually building your GUI on the self.root Tk instance, but then you're also calling Tk.__init__(self), which is initializing a blank Tk object (hence the second window). You need to pick one approach or the other; either (1) Don't inherit from Tk, don't call Tk.__init__(self), and just use self.root, or (2) Don't create a self.root object at all, call Tk.__init__(self), and simply use self everywhere you're currently using self.root.

OTHER TIPS

Please note that this appears to be a homework assignment for a class I teach. If you are tempted to use this example as your own please note two things.

  • The code has some problems so it's not the best thing to copy
  • The TAs and I are very aware that this code is online so you'll probably get busted
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top