Verwendung einer Variablen nach Eingabe in der GUI - get()

Fragen zu Tkinter.
Antworten
vokuhila
User
Beiträge: 3
Registriert: Samstag 12. Februar 2011, 12:26

Hallo Kollegen,
ich versuche zurzeit vergeblich folgendes:

Ich will eine eine einfache GUI programmieren, die drei Eingabefelder enthalten soll (dies hat auch funktioniert). Die Eingabefelder kommen dann, wenn ein bestimmtes Menü gewählt wurde.

Code: Alles auswählen

def AusgabeEingabe(): 
    lb = tkinter.Label(main, text="Eingabe1")
    lb.pack()
    b = tkinter.Entry(main)
    b.pack()
    lb= tkinter.Label(main, text="Eingabe2")
    lb.pack()
    e = tkinter.Entry(main)
    e.pack()
    lb = tkinter.Label(main, text="Eingabe3")
    lb.pack()
    a = tkinter.Entry(main)
    a.pack()
    lb = tkinter.Label(main, text="Ergebnis:")
    lb.pack
    ButtonBerechne = tkinter.Button(main, text = "Berechne", command = ermittle)
    ButtonBerechne.pack()
Dann will ich, dass die Inputvariable "e" (entspricht der Eingabe2) für einen Vergleich herangezogen wird:

Code: Alles auswählen

def ermittle():                                          
    eingabe = e.get()
    zahl = int(eingabe)
    if zahl < 12:
        lb["text"] = "passt"
    else:
        lb["text"] = "passt nicht"
  
Da erhalte ich jedoch folgende Fehlermeldung:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Programme\Python\lib\tkinter\__init__.py", line 1399, in __call__
return self.func(*args)
File "C:\Programme\Python\Progs\YMMGui", line 35, in ermittle
eingabe = e.get()
NameError: global name 'e' is not defined


Woran liegt das? Darf ich euch bitten, mir hier weiterzuhelfen?

Herzlichen Dank!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Woran es liegt, steht doch in der Fehlermeldung: e ist nicht bekannt.
Du hast e nur lokal definiert, allerdings nicht in derselben Funktion, in der du e verwenden willst.
Im Namensraum deiner Funktion ermittle() ist e unbekannt, folglich wird im globalen Namensraum gesucht und da gibt es in deinem Programm (zum Glück) anscheinend auch kein e.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

vokuhila hat geschrieben: Woran liegt das? Darf ich euch bitten, mir hier weiterzuhelfen?
Naja, die Fehlermeldung ist doch recht eindeutig. Der Name "e" existiert eben nicht im globalen Namensraum. Du bindest doch ein Objekt in der Funktion AusgabeEingabe() an den Namen "e". Sobald diese Funktion abgearbeitet ist, wird der Name wieder freigegeben.

Als kleines Beispiel:

Code: Alles auswählen

In [1]: def foo():
   ...:     a = 4
   ...:
   ...:

In [2]: foo()

In [3]: a
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)

C:\Dokumente und Einstellungen\nelson\Eigene Dateien\<ipython console> in <modul
e>()

NameError: name 'a' is not defined

In [4]: def bar():
   ...:     print a
   ...:
   ...:

In [5]: bar()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)

C:\Dokumente und Einstellungen\nelson\Eigene Dateien\<ipython console> in <modul
e>()

C:\Dokumente und Einstellungen\nelson\Eigene Dateien\<ipython console> in bar()

NameError: global name 'a' is not defined
Lösen kann man so etwas, indem man den Funktionen Parameter übergibt und Objekte zurückliefert:

Code: Alles auswählen

In [6]: def foo():
   ...:     return "Hallo"
   ...:

In [7]: def bar(data):
   ...:     print data
   ...:
   ...:

In [8]: d = foo()

In [9]: d
Out[9]: 'Hallo'

In [10]: bar(d)
Hallo

In [11]: bar(foo())
Hallo
Das sind übrigens absolute Basics. Du solltest Dir da imho erst noch einmal die Grundlagen genauer ansehen und vertiefen; GUIs sind für Anfänger idR. eher ein Hemmschuh und zu aufwendig. Zu Deinem Code wäre sonst auch noch einiges zu sagen... das überlasse ich mal BlackJack, der ist da immer sehr präzise und genau :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
daemonTutorials
User
Beiträge: 171
Registriert: Sonntag 6. Februar 2011, 12:06
Kontaktdaten:

Erstmal, falls du die Variablen o. Objekte global verfügbar machen willst, nutz nicht "global", ja?

Und die Namen sollten eindeutiger sein.

Soll die Methode "AusgabeEingabe" eine Kapselung der GUI sein, oder warum hast du das gekapselt! Ich würde ja entweder in eine Main reinpacken, oder auch prozedural machen! Also das "def AusgabeEingabe():" wegnehmen und die ganzen Tabs vorne wegmachen, dann klappt das!

Du kannst du die Methode "ermittle" in AusgabeEingabe packen, wenn diese nicht von außerhalb gebraucht wird!

Meine Codelösung:

Code: Alles auswählen

def AusgabeEingabe(): 
    # content of DaemonTutorials
    main = tkinter.Tk()
    lb = tkinter.Label(main, text="Eingabe1")
    lb.pack()
    b = tkinter.Entry(main)
    b.pack()
    lb= tkinter.Label(main, text="Eingabe2")
    lb.pack()
    e = tkinter.Entry(main)
    e.pack()
    lb = tkinter.Label(main, text="Eingabe3")
    lb.pack()
    a = tkinter.Entry(main)
    a.pack()
    lb = tkinter.Label(main, text="Ergebnis:")
    lb.pack
    # Der Funktion muss "e" bekannt sein und muss vor "ButtonBerechne" stehen um von command anerkannt zu werden!
    def ermittle():                                          
        eingabe = e.get()
        zahl = int(eingabe)
        if zahl < 12:
            # Nehme nicht lb["text"] = "passt"
            # sondern
            lb.config(text = "passt")
        else:
            # Nehme nicht lb["text"] = "passt nicht"
            # sondern
            lb.config(text = "passt nicht")
    
    ButtonBerechne = tkinter.Button(main, text = "Berechne", command = ermittle)
    ButtonBerechne.pack()
    # Pack ich einfach mal dazu!
    main.mainloop()
Das müsste klappen, vorrausgesetzt du hast auch eine Mainloop!

Aufruf:

Code: Alles auswählen

>>> import ausgabeEingabe
>>> ausgabeEingabe()

LG Maik
vokuhila
User
Beiträge: 3
Registriert: Samstag 12. Februar 2011, 12:26

Herzlichen Dank für Eure Tipps!
Antworten