Brauche Hilfe bei meinen Info-Projekt, BMI- Rechner

Fragen zu Tkinter.
Antworten
eXodus
User
Beiträge: 6
Registriert: Sonntag 3. März 2013, 09:59

Hallo,
Für die Schule sollen wir einen BMI (Body Mass Index) Rechner schreiben. Soweit so gut, die Berechnung und Ausgabe, sowie eine Interpretation des berechneten BMIs funktonieren bereits.

Jedoch sollen wir eine Eingabemöglichkeit für das Geschlecht schreiben (was auch noch klappt) und jenachdem ob dort "maennlich" oder "weiblich" eingegeben wird, soll sich die Farbe des Frames, nachdem man auf den Berechnen Button geklickt hat, zu blaub (bei maennlich) oder pink/ rosa (bei weiblich) ändern.

Mein Code:

Code: Alles auswählen

from tkinter import *

def bmiberechnung(Groesse, Gewicht):
    BMIm = (float(Gewicht)/(float(Groesse)*float(Groesse)))
    return (BMIm)

def Button_Berechnen_Clickm():

# Uebernahme der Daten
    Gewicht = entryGewicht.get()
    Groesse = entryGroesse.get()

    # Verarbeitung der Daten
    BMI = bmiberechnung(Groesse, Gewicht)

    # Anzeige der Daten
    anzeigeBMI = '{0:.2f}'. format(BMI)
    labelWertBMI.config(text=anzeigeBMI)

    # Abfrage fuer das Geschlecht, Frame- Farbe aendern
    if  entryGeschlecht == "maennlich":
        frameEingaben.config(background="#0000FF")
    if entryGeschlecht == "weiblich":
        frameEingaben.config(background="#FF00BF")

# Abfrage fuer die Interpretation des BMI
    if float(anzeigeBMI) <= 16:
        labelAuswertung2.config(text="Starkes Untergewicht", background="#2E2EFE")
    if float(anzeigeBMI) > 16:
        labelAuswertung2.config(text="maessiges Untergewicht", background="#0000FF")
    if float(anzeigeBMI) > 17:
        labelAuswertung2.config(text="leichtes Untergewicht", background="#A9BCF5")
    if float(anzeigeBMI) > 18:
        labelAuswertung2.config(text="Normalgewicht", background="#088A08")
    if float(anzeigeBMI) > 25:
        labelAuswertung2.config(text="Praedipositas/ Uebergewicht", background="#FFFF00")
    if float(anzeigeBMI) > 30:
         labelAuswertung2.config(text="Adipositas Grad I", background="#FF8000")
    if float(anzeigeBMI) >35:
         labelAuswertung2.config(text="Adipositas Grad II", background="#DF0101")
    if float(anzeigeBMI) >= 40:
         labelAuswertung2.config(text="Adipositas Grad III", background="#610B0B")



# Erzeugung des Fensters
tkFenster = Tk()
tkFenster.title("BMI- Rechner")
tkFenster.geometry('700x500')
# Rahmen fuer die Ueberschrift
frameUeberschrift = Frame(master=tkFenster,
                          background="#889E9D")
frameUeberschrift.place(x=5, y=5, width=690, height=45)
# Rahmen fuer die Eingaben
frameEingaben = Frame(master=tkFenster,
                      background="#ACFA58")
frameEingaben.place(x=5, y=60, width=690, height=100)

# Rahmen fuer die Verarbeitung
frameVerarbeitung = Frame(master=tkFenster,
                          background="#FBD975")
frameVerarbeitung.place(x=5, y=172, width=690, height=44)
# Rahmen fuer die Ausgaben
frameAusgabe = Frame(master=tkFenster,
                      background="#ACFA58")
frameAusgabe.place(x=5, y=221, width=690, height=101)
# Rahmen fuer die Auswertung
frameAuswertung = Frame(master=tkFenster,
                       background="#ACFA58")
frameAuswertung.place(x=5, y=325, width=690, height=168)
# Label fuer die Ueberschrift
labelUeberschrift = Label(master=frameUeberschrift,
                          background="white",
                          text="BMI- Rechner")
labelUeberschrift.place(x=270, y=12, width=190, height=20)
# Label mit Aufschrift Gewicht
labelgewicht = Label(master=frameEingaben,
                             background="white",
                             text="Gewicht in [kg]")
labelgewicht.place(x=385, y=10, width=175, height=20)
# Label mit Aufschrift Alter
labelalter = Label(master=frameEingaben,
                             background="white",
                             text="Alter in [Jahren]")
labelalter.place(x=5, y=10, width=175, height=20)
# Label mit Aufschrift Groesse
labelgroesse = Label(master=frameEingaben,
                             background="white",
                             text="Groesse in [m]")
labelgroesse.place(x=385, y=60, width=175, height=20)
# Label mit Aufschrift Vorname
labelvorname = Label(master=frameEingaben,
                             background="white",
                             text="Dein Vorname")
labelvorname.place(x=5, y=35, width=175, height=20)
# Label mit Aufschrift name
labelname = Label(master=frameEingaben,
                             background="white",
                             text="Dein Nachname")
labelname.place(x=385, y=35, width=175, height=20)
# Label mit Aufschrift Geschlecht
labelGeschlecht = Label(master=frameEingaben,
                        background="white",
                        text="Dein Geschlecht")
labelGeschlecht.place(x=5, y=60, width=175, height=20)
# Entry fuer das Alter
entryAlter = Entry(master=frameEingaben)
entryAlter.place(x=210, y=10, width=80, height=20)
# Entry fuer das Gewicht
entryGewicht = Entry(master=frameEingaben)
entryGewicht.place(x=580, y=10, width=80, height=20)
# Entry fuer den Vornamen
entryVorname = Entry(master=frameEingaben)
entryVorname.place(x=210, y=35, width=80, height=20)
# Entry fuer den Namen
entryName = Entry(master=frameEingaben)
entryName.place(x=580, y=35, width=80, height=20)
# Entry fuer die Groesse
entryGroesse = Entry(master=frameEingaben)
entryGroesse.place(x=580, y=60, width=80, height=20)
# Entry fuer das Geschlecht
entryGeschlecht = Entry(master=frameEingaben)
entryGeschlecht.place(x=210, y=60, width=80, height=20)
# Button Berechnen m
buttonBerechnenm = Button(master=frameVerarbeitung,
                         text="berechnen",
                         command=Button_Berechnen_Clickm)
buttonBerechnenm.place(x=290, y=12, width=100, height=20)
# Label mit Aufschrift Dein BMI
labelBMI = Label(master=frameAusgabe,
                          background="white",
                          text="Dein BMI ist:")
labelBMI.place(x=130, y=30, width=175, height=20)
# Label fuer den Wert des BMI
labelWertBMI = Label(master=frameAusgabe,
                              background="white",
                              text="")
labelWertBMI.place(x=330, y=30, width=100, height=20)
# Label fuer Auswertung
labelAuswertung = Label(master=frameAuswertung,
                  background="white",
                   text="Auswertung deines BMI:")
labelAuswertung.place(x=370, y=90, width=200, height=20)
# Label fuer Auswertung
labelAuswertung2 = Label(master=frameAuswertung,
                  background="white",
                   text="")
labelAuswertung2.place(x=370, y=120, width=200, height=20)


# Aktivierung des Fensters
tkFenster.mainloop()
Das Fett makierte habe ich bereits versucht für das Problem, jedoch funktioniert es nicht. es erscheint kein Error, es ändert sich einfach nicht..

Hoffe jemand kann mir helfen :)
Zuletzt geändert von eXodus am Sonntag 3. März 2013, 16:11, insgesamt 2-mal geändert.
BlackJack

@eXodus: Du vergleichst Widget-Objekte mit Zeichenketten. Das ist *immer* unwahr weil das ein Vergleich zwischen Äpfeln und Birnen ist. Du willst nicht das Widget vergleichen, sondern den Text der dort eingegeben wurde. Wie man an den Text kommt, solltest Du wissen, denn das machst Du mit anderen Eingabefeldern ja schon richtig.

``return`` ist keine Funktion, also gehören da auch keine unnötigen Klammern um den Ausdruck. Ausserdem lohnt es sich nicht das Ergebnis der BMI-Berechnung in der Funktion an einen Namen zu binden der ausschliesslich in der nächsten Zeile für das ``return`` verwendet wird.

Statt die Grösse des Fensters fest vorzugeben und die Widgets mit `place()` absolut zu platzieren, solltest Du die GUI mit `grid()` und/oder `pack()` aufbauen und gegebenenfalls zusätzlichen `Frame`\s um Elemente zu gruppieren. Sonst hast Du eine GUI die nur auf dem Rechner auf dem sie erstellt wurde ordentlich aussieht und auf anderen Systemen abhängig von vielen Faktoren wie Fenstermanager, Bildschirmauflösung, Schriftgrössen, Theme, und so weiter, schlecht aussehen kann, oder sogar tatsächlich unbenutzbar sein kann.

Statt Texteingaben für das Geschlecht wäre es einfacher für den Anwender und auch sicherer, wenn man eine Drop-Down-Auswahl oder Radiobuttons für diese Wahl verwendet.

Diese Entscheidung nur für die Farbe des Rahmens zu verwenden erscheint mir unsinnig, denn eigentlich wichtiger wäre doch das Ergebnis entsprechend zu interpretieren.
eXodus
User
Beiträge: 6
Registriert: Sonntag 3. März 2013, 09:59

BlackJack hat geschrieben:@eXodus: Du vergleichst Widget-Objekte mit Zeichenketten. Das ist *immer* unwahr weil das ein Vergleich zwischen Äpfeln und Birnen ist. Du willst nicht das Widget vergleichen, sondern den Text der dort eingegeben wurde. Wie man an den Text kommt, solltest Du wissen, denn das machst Du mit anderen Eingabefeldern ja schon richtig.
Habe jetzt eine Listbox eingefügt, wie kann ich es dann per if Abfrage oder sonst wie machen, dass ich dann je nachdem was bei der listbox ausgewählt wurde die farbe des frames ändert?
BlackJack

@eXodus: Wenn das *sofort* nach Änderung der Auswahl passieren soll, dann gibt es keine wirklich schöne Lösung mit `Listbox`. Darum habe ich das Widget auch nicht vorgeschlagen. `Menubutton` oder `Radiobutton`\s sind dafür besser geeignet. Ich würde Radiobuttons nehmen, denn es gibt nur zwei Auswahlmöglichkeiten und es ist genug Platz in der GUI vorhanden. Wobei wir bei einem weiteren Nachteil von `place()` wären: Es ist unverhältnismässig viel Arbeit an einer GUI etwas zu ändern, wie beispielsweise irgend wo Widgets einzufügen und dafür andere Verschieben zu müssen.
eXodus
User
Beiträge: 6
Registriert: Sonntag 3. März 2013, 09:59

Habe es jetzt dank den Radiobuttons hinbekommen, danke :)

mit dem grid() und pack() werd ich mich auch mal auseinander setzen. haben nur halt letztens erst in der schule mit python angefangen und dementsprechend noch nicht wirklich viel gemacht..


/edit:
Eine Frage hab ich jetzt noch: Ist es möglich die Eingabe von Gewicht und Größe vorher abzufangen und zu testen ob es wirklich zahlen sind und dann ggf. in einem Label eine Meldung auszugeben, dass man zahlen eingeben muss? Anstatt dass dann sofort ein Traceback in der Konsole erscheint.?
BlackJack

@eXodus: Dafür gibt es die Ausnahmebehandlung mit ``try`` und ``except``.
eXodus
User
Beiträge: 6
Registriert: Sonntag 3. März 2013, 09:59

Okay danke, dann werd ich mich es mal versuchen :)
Antworten