Python, Werte einlesen und zurückgeben

Fragen zu Tkinter.
Antworten
mugen-Type-R
User
Beiträge: 4
Registriert: Sonntag 27. Juni 2010, 15:01

Hallo allerseits.
Gehts um folgendes. Ich will eine "mini"-Formelsammlung mittels Python schreiben. Soweit sogut, doch nun bin ich auf ein Punkt gestoßen, wo ich net weiter komme. Hoffe mir wird hier geholfen.
Die Formels müsste so aussehen.Bild
Gedanke: Bei Punkt 1. sollte man die Werte eingeben und wenn man auf Berechnen drücke, dan soll der Antwort im oberen Label (2.) erscheinen.
1.Frage:
Wie kann ich es machen, dass die Werte eingelesen und übernommen werden ( bei 1.)
Ich habe es mal mit .get() versucht. Problem: Die Werte werden dann zwar übernommen doch nicht in die Fkt. einbezogen.
2.Frage:
Was muss ich machen, damit das Ergebniss im oberen Label (bei 2.) erscheint? Da habe ich leider keinen Ansatz für.
Weiteres Problem: Ich darf Fkt. "class" und "self" nicht benutzen.

Code:

Code: Alles auswählen

import Tkinter

def ende():
    main.withdraw()

    
        # FUNKTIONEN

def fma(F=0,m=0,a=0):
    F = float(F)    # -> hier habe ich mit E1.get() versucht
    m = float(m)
    a = float(a)
    if m > 0 and a > 0:
        F=m*a
        print("F = %.2f N" % F)
        print("m = %.2f kg" % m)
        print("a = %.2f m/s^2" % a)
        return
    if F > 0 and a > 0:
        m=F/a
        print("F = %.2f N" % F)
        print("m = %.2f kg" % m)
        print("a = %.2f m/s^2" % a)
        return
    if F > 0 and m > 0:
        a=F/m
        print("F = %.2f N" % F)
        print("m = %.2f kg" % m)
        print("a = %.2f m/s^2" % a)
        return
    
def fml(F=0,M=0,l=0):
    F = float(F)
    M = float(M)
    l = float(l)
    if M > 0 and l > 0:
        F=M*l
        print("F = %.2f N" % F)
        print("M = %.2f Nm" % M)
        print("l = %.2f m" % l)
        return
    if F > 0 and l > 0:
        M=F/l
        print("F = %.2f N" % F)
        print("M = %.2f Nm" % M)
        print("l = %.2f m" % l)
        return
    if F > 0 and M > 0:
        l=F/M
        print("F = %.2f N" % F)
        print("M = %.2f Nm" % M)
        print("l = %.2f m" % l)
        return

def pfa(p=0,F=0,A=0):
    p = float(p)
    F = float(F)
    A = float(A)
    if p > 0 and F > 0:
        A=F/p
        print("p = %.2f Pa" % p)
        print("F = %.2f N" % F)
        print("A = %.2f m^2" % A)
        return
    if p > 0 and A > 0:
        F=p*A
        print("p = %.2f Pa" % p)
        print("F = %.2f N" % F)
        print("A = %.2f m^2" % A)
        return
    if F > 0 and A > 0:
        p=F/A
        print("p = %.2f Pa" % p)
        print("F = %.2f N" % F)
        print("A = %.2f m^2" % A)
        return


        # Hauptprogramm
    
main = Tkinter.Tk()
main.title("Formelsammlung")
main.geometry("480x220")


        # FELDER/FRAMES
    
#FrameAL mit Anzeige-Label
frameal = Tkinter.Frame(main)
frameal.pack(fill = Tkinter.X)
labelal = Tkinter.Label(frameal, bg="#FFFFFF", bd=4,
                        relief = "sunken", anchor="e")
labelal.pack(fill = Tkinter.X, pady = 10)

#FrameA
framea = Tkinter.Frame(main)
framea.pack(fill = Tkinter.X)
#FrameB
frameb = Tkinter.Frame(main)
frameb.pack(fill = Tkinter.X)
#FrameC
framec = Tkinter.Frame(main)
framec.pack(fill = Tkinter.X)


        # LABELS

#Label One
label1 = Tkinter.Label(framea, text = "F = m*a")
label1["font"] = "Courier 12 italic"
label1["height"] = 2
label1["width"] = 15
label1["borderwidth"] = 4
label1["relief"] = "groove"
label1["bg"] = "#FFFFFF"
label1["fg"] = "#000000"
label1["anchor"] = "w"
label1.pack(side = Tkinter.LEFT)

#Label 2
label2 = Tkinter.Label(framea, text = "M = F*l")
label2["font"] = "Courier 12 italic"
label2["height"] = 2
label2["width"] = 15
label2["borderwidth"] = 4
label2["relief"] = "groove"
label2["bg"] = "#FFFFFF"
label2["fg"] = "#000000"
label2["anchor"] = "w"
label2.pack(side = Tkinter.LEFT)

#Label 3
label3 = Tkinter.Label(framea, text = "p = F/A")
label3["font"] = "Courier 12 italic"
label3["height"] = 2
label3["width"] = 15
label3["borderwidth"] = 4
label3["relief"] = "groove"
label3["bg"] = "#FFFFFF"
label3["fg"] = "#000000"
label3["anchor"] = "w"
label3.pack(side = Tkinter.LEFT)



        #ENTRYS/EINGABEN

# Krafteingabe
E1 = Tkinter.Entry(frameb, width = 5)
E1.insert(0, 'F')
E1.pack(side = Tkinter.LEFT)
E2 = Tkinter.Entry(frameb, width = 4)
E2.insert(0, 'm')
E2.pack(side = Tkinter.LEFT)
E3 = Tkinter.Entry(frameb, width = 4)
E3.insert(0, 'a')
E3.pack(side = Tkinter.LEFT)
# Button1
b1 = Tkinter.Button(frameb, text = "Berechnen",
                    activebackground = "yellow", command = fma)
b1.pack(side = Tkinter.LEFT)

# Dregmomeneingabe
E4 = Tkinter.Entry(frameb, width = 5)
E4.insert(0, 'M')
E4.pack(side = Tkinter.LEFT)
E5 = Tkinter.Entry(frameb, width = 4)
E5.insert(0, 'F')
E5.pack(side = Tkinter.LEFT)
E6 = Tkinter.Entry(frameb, width = 4)
E6.insert(0, 'l')
E6.pack(side = Tkinter.LEFT)
# Button1
b2 = Tkinter.Button(frameb, text = "Berechnen",
                    activebackground = "yellow", command = fml)
b2.pack(side = Tkinter.LEFT)

# Druckneingabe
E7 = Tkinter.Entry(frameb, width = 5)
E7.insert(0, 'p')
E7.pack(side = Tkinter.LEFT)
E8 = Tkinter.Entry(frameb, width = 4)
E8.insert(0, 'F')
E8.pack(side = Tkinter.LEFT)
E9 = Tkinter.Entry(frameb, width = 4)
E9.insert(0, 'A')
E9.pack(side = Tkinter.LEFT)
# Button1
b3 = Tkinter.Button(frameb, text = "Berechnen",
                    activebackground = "yellow", command = pfa)
b3.pack(side = Tkinter.LEFT)


main.mainloop()
Falls sowas schonmal besprochen wurde, bitte ich um den Link, weil ich in der Suche nichts vergleichbares gefunden habe.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Dein Code ist mir zum Durchwühlen zu grausam. Aber das hier sollte dir helfen, das gewünschte Ziel zu erreichen:

Code: Alles auswählen

import Tkinter as tk

def add():
    res_fld.delete("0","end")
    try: res_fld.insert("0",str(int(op1_fld.get()) + int(op2_fld.get())))
    except ValueError: res_fld.insert("0","Fehlerhafte Operanden")

root = tk.Tk()
op1_fld = tk.Entry(root)
op2_fld = tk.Entry(root)
res_fld = tk.Entry(root)
add_btn = tk.Button(root,text="Addiere",command=add)
op1_fld.pack()
op2_fld.pack()
res_fld.pack()
add_btn.pack()
root.mainloop()
mugen-Type-R
User
Beiträge: 4
Registriert: Sonntag 27. Juni 2010, 15:01

Sry wenn es für einen oder anderen so "grausam" erscheint. Bin absoluter Anfänger.
Arbeite meist nach der Ornung bzw. versuche die Reihenfolgezu behalten. Z.B., dass erst die Fkt, kommt, dann das Hauptprogrammm, Frames, Labels, etc.
Vlt. is es in Python net von Vorteil, aber ich komme damit besser (noch?) zurecht.
Grade mal 4 Wochen. Lernen Python grade in der Uni und zum Ablschluß sollten wir ein kleines Programm, Spiel etc. schreiben :)
Habe dein Rat zum Herzen genommen :) doch ein kleiner Fehler ist noch vorhanden.
Habe nun das Ausgabe-Label durch Entry erstetzt und die Berechnung zumindest scheint zu funktionieren.
Doch wenn man z.B. ein Buchstabe eintippt, dann spuckt er nichts (im Entry) aus.
Was habe ich flasch gemacht? Wenns geht bitte erklären :roll:

So siehts mom. aus:

Code: Alles auswählen

import Tkinter

def ende():
    main.withdraw()

    
        # FUNKTIONEN

        
def fma(F=0,m=0,a=0):
    F = float(E1.get())
    m = float(E2.get())
    a = float(E3.get())
    Ber.delete("0","end")
    if m > 0 and a > 0:
        try: Ber.insert("0", str(m*a))
        except ValueError: Ber.insert("0","Zahl eingeben")
    if F > 0 and a > 0:
        try: Ber.insert("0", str(F/a))
        except ValueError: Ber.insert("0","Zahl eingeben")
    if F > 0 and m > 0:
        try: Ber.insert("0", str(F/m))
        except ValueError: Ber.insert("0","Zahl eingeben")
    
def fml(F=0,M=0,l=0):
    F = float(E4.get())
    M = float(E5.get())
    l = float(E6.get())
    Ber.delete("0","end")
    if M > 0 and l > 0:
        try: Ber.insert("0", str(M*l))
        except ValueError: Ber.insert("0","Zahl eingeben")
    if F > 0 and l > 0:
        try: Ber.insert("0", str(F/l))
        except ValueError: Ber.insert("0","Zahl eingeben")
    if F > 0 and M > 0:
        try: Ber.insert("0", str(F/M))
        except ValueError: Ber.insert("0","Zahl eingeben")

def pfa(p=0,F=0,A=0):
    p = float(E7.get())
    F = float(E8.get())
    A = float(E9.get())
    if p > 0 and F > 0:
        try: Ber.insert("0", str(F/p))
        except ValueError: Ber.insert("0","Zahl eingeben")
    if p > 0 and A > 0:
        try: Ber.insert("0", str(p*A))
        except ValueError: Ber.insert("0","Zahl eingeben")
    if F > 0 and A > 0:
        try: Ber.insert("0", str(F/A))
        except ValueError: Ber.insert("0","Zahl eingeben")


        # Hauptprogramm
    
main = Tkinter.Tk()
main.title("Formelsammlung")
main.geometry("480x220")


        # FELDER/FRAMES 
#FrameAL mit Anzeige-Label
frameal = Tkinter.Frame(main)
frameal.pack(fill = Tkinter.X)
#labelal = Tkinter.Label(frameal, text = "0", bg="#FFFFFF", bd=4,
#                        relief = "sunken", anchor="e")
#labelal.pack(fill = Tkinter.X, pady = 10)

#FrameA
framea = Tkinter.Frame(main)
framea.pack(fill = Tkinter.X)
#FrameB
frameb = Tkinter.Frame(main)
frameb.pack(fill = Tkinter.X)
#FrameC
framec = Tkinter.Frame(main)
framec.pack(fill = Tkinter.X)
#FrameD
#framed = Tkinter.Frame(main)
#framed.pack(fill = Tkinter.X)
#FrameE
#framee = Tkinter.Frame(main)
#framee.pack(fill = Tkinter.X)
#FrameF
#framef = Tkinter.Frame(main)
#framef.pack(fill = Tkinter.X)


        # LABELS

#Label One
label1 = Tkinter.Label(framea, text = "F = m*a")
label1["font"] = "Courier 12 italic"
label1["height"] = 2
label1["width"] = 15
label1["borderwidth"] = 4
label1["relief"] = "groove"
label1["bg"] = "#FFFFFF"
label1["fg"] = "#000000"
label1["anchor"] = "w"
label1.pack(side = Tkinter.LEFT)

#Label 2
label2 = Tkinter.Label(framea, text = "M = F*l")
label2["font"] = "Courier 12 italic"
label2["height"] = 2
label2["width"] = 15
label2["borderwidth"] = 4
label2["relief"] = "groove"
label2["bg"] = "#FFFFFF"
label2["fg"] = "#000000"
label2["anchor"] = "w"
label2.pack(side = Tkinter.LEFT)

#Label 3
label3 = Tkinter.Label(framea, text = "p = F/A")
label3["font"] = "Courier 12 italic"
label3["height"] = 2
label3["width"] = 15
label3["borderwidth"] = 4
label3["relief"] = "groove"
label3["bg"] = "#FFFFFF"
label3["fg"] = "#000000"
label3["anchor"] = "w"
label3.pack(side = Tkinter.LEFT)



        #ENTRYS/EINGABEN

# Krafteingabe
E1 = Tkinter.Entry(frameb, width = 5)
E1.insert("0", "F")
E1.pack(side = Tkinter.LEFT)
E2 = Tkinter.Entry(frameb, width = 4)
E2.insert("0", "m")
E2.pack(side = Tkinter.LEFT)
E3 = Tkinter.Entry(frameb, width = 4)
E3.insert("0", "a")
E3.pack(side = Tkinter.LEFT)
Ber = Tkinter.Entry(frameal)
Ber.pack()
# Button1
b1 = Tkinter.Button(frameb, text = "Berechnen",
                    activebackground = "yellow", command = fma)
b1.pack(side = Tkinter.LEFT)

# Drehmomeneingabe
E4 = Tkinter.Entry(frameb, width = 5)
E4.insert(0, 'M')
E4.pack(side = Tkinter.LEFT)
E5 = Tkinter.Entry(frameb, width = 4)
E5.insert(0, 'F')
E5.pack(side = Tkinter.LEFT)
E6 = Tkinter.Entry(frameb, width = 4)
E6.insert(0, 'l')
E6.pack(side = Tkinter.LEFT)
# Button1
b2 = Tkinter.Button(frameb, text = "Berechnen",
                    activebackground = "yellow", command = fml)
b2.pack(side = Tkinter.LEFT)

# Druckeingabe
E7 = Tkinter.Entry(frameb, width = 5)
E7.insert(0, 'p')
E7.pack(side = Tkinter.LEFT)
E8 = Tkinter.Entry(frameb, width = 4)
E8.insert(0, 'F')
E8.pack(side = Tkinter.LEFT)
E9 = Tkinter.Entry(frameb, width = 4)
E9.insert(0, 'A')
E9.pack(side = Tkinter.LEFT)
# Button1
b3 = Tkinter.Button(frameb, text = "Berechnen",
                    activebackground = "yellow", command = pfa)
b3.pack(side = Tkinter.LEFT)



        # BUTTONS
#b1 = Tkinter.Button(frameb, text = "berechne",
#                    activebackground = "yellow", command = None)
#b1.pack(side = Tkinter.LEFT)
#b2 = Tkinter.Button(framed, text = "Ergebniss",
#                    activebackground = "yellow", command = None)
#b2.pack(side = Tkinter.LEFT)
#b3 = Tkinter.Button(framef, text = "Ergebniss",
#                    activebackground = "yellow", command = None)
#b3.pack(side = Tkinter.LEFT)



main.mainloop()
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Wenn du Code kopierst oder nahezu identisch schreibst, dann solltest du dir ernsthafte Gedanken über die Verwendung von Funktionen machen. Numerierst du Namen, dann möchtest du Listen und Schleifen benutzen. Damit kann dein Programm auf einen Bruchteil zusammengestaucht werden. Außerdem möchtest du keinen Code auf Modulebene haben und richtige Bezeichner vergeben.

Sebastian
Das Leben ist wie ein Tennisball.
BlackJack

@mugen-Type-R: Überleg Dir doch mal was passiert wenn Du einen Buchstaben statt einer Ziffer eingibst. Wo genau das in dem Programm zu einem Problem führt. Nicht da wo Du Deine Ausnahmebehandlung stehen hast. Du kannst es aus zwei Richtungen angehen: Überlegen was Schritt für Schritt passiert wenn Du einen Buchstaben eingibst und die Schaltfläche betätigst, oder von Deiner Ausnahmebehandlung aus rückwärts durch den Quelltext gehen und überlegen warum der Programmfluss gar nicht erst bis dahin kommt.

Wenn das reine überlegen nicht ausreicht, dann füge mal ein paar ``print``-Anweisungen ein, um Deine Annahmen zu überprüfen.

Der Code auf Modulebene sollte in einer Funktion verschwinden und Du solltest GUI und Berechnung sauberer trennen. Die Berechnungsfunktionen sollten ihre Werte als Argumente bekommen und nicht selbst aus der GUI auslesen. So kann man die weder einfach testen noch wiederverwenden. Die Argumente werden jetzt ja gar nicht mehr verwendet. Ist Dir das nicht komisch vorgekommen?
BlackJack

Noch eine Anmerkung zur GUI -- die sieht bei mir so aus:

Bild

Ein schönes Beispiel warum man keine grössen fest vorgeben sollte. Wenn ich die harte Grössenvorgabe für das Fenster herausnehme, wird wenigstens alles angezeigt:

Bild

Ideal ist das natürlich immer noch nicht. Du solltest die zusammengehörigen Widgets vielleicht noch in jeweils einem eigenen `Frame` zusammenfassen, bevor Du sie in das Hauptfenster steckst.
mugen-Type-R
User
Beiträge: 4
Registriert: Sonntag 27. Juni 2010, 15:01

Wie erähnt, bin ich kein Profi und bin gerade dabei Python zu erlernen.
Ich weiß, dass man z.B. die Def. in einem eigene Modul speichern und den dann importieren könnte. Oder geht das nicht? Wir hatten das noch nicht.
Class und self hatten wir auch nicht und deshalb dürfen wir es auch nicht benutzen. Laut I-net wäre aber mittels class&self einfacher gewesen. Oder täusche ich mich?

@ BlackJack
Ich habe den Variablen F,a, etc. "float" vergeben. Ich gehe davon aus, dass dadurch die Buchstaben ("strings"?!) nicht übernommen werden können?! Ist es das, woran es liegt?
Positionierung: Ich begreif mom. noch nicht, was ich wo nutzen soll. Es gibt fill, anchor, etc. Das muss ich noch verstehen.
Wie kommt es, dass bei mir wie im Bild das Fenster dargestellt wird und bei dir anders?
BlackJack

@mugen-Type-R: Probier es doch einfach mal aus was mit Zeichenketten mit Buchstaben passiert wenn man sie an `float()` übergibt. Wobei die Rechenfunktionen IMHO schon Zahlen bekommen sollten und keine Zeichenketten. Die müsste man also *vor* dem Aufruf schon umwandeln.

Mit Klassen ginge das einfacher. Ohne Klassen müsste man "closures" verwenden. Ohne eines von beidem kann man das IMHO nicht sauber umsetzen.

Bei der Darstellung spielen ganz viele Faktoren mit hinein: Betriebssystem bzw. Fenstersystem, Bildschirmauflösung, global vorgegebene Schriftgrössen und Schriftarten, und so weiter. Das kann bei jedem anders aussehen. Deshalb kann man nicht mit fest vorgegebenen Grössen arbeiten. Das ist aber kein Problem wenn man die Einzelteile in Frames gruppiert und nicht versucht absolute Zahlen solange anzupassen bis es auf dem *eigenen* Rechner gut aussieht. Man kann Widgets in `Frame`\s packen wie man das auch mit dem Hauptfenster machen kann, und diese `Frame`\s kann man wieder in andere `Frame`\s oder in das Hauptfenster packen. Wichtig ist, dass man bei `pack()` in einem Container immer nur eine `side` verwendet, sonst kann man komische Ergebnisse bekommen.

Bei Deiner GUI bietet es sich an die Widgets für eine Formel in einen `Frame` zu stecken und diese drei `Frame`\s dann nebeneinander in ein Container-Widget zu packen. Da alle drei recht ähnlich aufgebaut sind, sollte man das Erstellen vielleicht in eine Funktion auslagern.

Aber als ersten Schritt würde ich die Berechnungen von der GUI trennen. Werte sollten da als Argumente hinein- und als Rückgabewert herauskommen.
Antworten