Seite 1 von 1
Zahlen mittels Entry Feld einlesen
Verfasst: Dienstag 30. Oktober 2012, 16:19
von AnyOne
Hallo Community,
ich bin neu in der Python Programmiersprache, habe aber vorher bereits C und C++ gelernt. Momentan entwickle ich eine GUI, mit welcher der User Konstanten für eine Berechnung festlegen können soll. Ich habe mir bereits mehrere Seiten im Internet zum Thema Tkinter und GUI Programmierung durchgelesen, aber irgendwie verstehe ich den Zusammenhang zwischen dem Entry-Feld und dem Auslesen des Entry-Feldes nicht.
Wenn ich jetzt folgenden Code erstelle:
Code: Alles auswählen
schOffsetX = tk.StringVar()
getConst_schOffsetXLabel = tk.Label(self.getConst, text = "schOffsetX")
getConst_schOffsetXEntry = tk.Entry(self.getConst, textvariable = self.schOffsetX)
Wie komme ich da an die vom Nutzer eingegebene Zahl?
Ich programmiere hier eine Klasse und dieser Ausschnitt befindet sich in der Funktion "getConstants(self):". Ausgelesen soll das Feld erst, wenn der Nutzer auf "Next" klickt, also in der Funktion getConstNext()
Code: Alles auswählen
getConst_NextButton = tk.Button(self.getConst, text = "Weiter", command = self.getConstNext)
Die Ausgelesene Zahl muss dann global für alle Funktionen der Klasse zur Verfügung stehen, da diese an mehreren Stellen benötigt wird.
Strings konnte ich immer problemlos mit self.<Variable>.get() auslesen, aber das funktioniert hier nicht. Da moniert mein eclipse immer sofort, dass das Attribut 'get' nicht für ein 'int' Objekt verfügbar sei. Sorry, wenn diese Frage für viele vielleicht zu doof klingen mag, aber ich komme da leider wirklich nicht weiter

Vielen Dank für eure Hilfe!
Viele Grüße
Dennis
Re: Zahlen mittels Entry Feld einlesen
Verfasst: Dienstag 30. Oktober 2012, 17:42
von wuf
Hi AnyOne
Willkommen im Forum. Da musst du aber die Bücher (Tutorials) nochmals gründlich durchlesen. Hier eine Snippet zum ausprobieren:
Code: Alles auswählen
try:
#~~ For Python 2.x
import Tkinter as tk
except ImportError:
#~~ For Python 3.x
import tkinter as tk
def get_constant():
label_var.set(entry_var.get())
print(entry_var.get())
app_win = tk.Tk()
#schOffsetX = tk.StringVar()
#getConst_schOffsetXLabel = tk.Label(self.getConst, text = "schOffsetX")
#getConst_schOffsetXEntry = tk.Entry(self.getConst, textvariable = self.schOffsetX)
label_var = tk.StringVar()
entry_var = tk.StringVar()
constant_display = tk.Label(app_win, textvariable=label_var, relief='raised',
width=15)
constant_display.pack(pady=5)
constant_entry = tk.Entry(app_win, textvariable=entry_var, bg='white')
constant_entry.pack(pady=5)
tk.Button(app_win, text="Konstante ins Label transferieren!",
command=get_constant).pack(pady=5)
app_win.mainloop()
Gruß wuf

Re: Zahlen mittels Entry Feld einlesen
Verfasst: Mittwoch 31. Oktober 2012, 11:10
von AnyOne
Hallo wuf,
vielen Dank für deine schnelle und hilfreiche Antwort! Ich habe dein Skript ausprobiert und einmal durchdacht (natürlich hat es funktioniert, woran ich auch zu keiner Zeit gezweifelt habe

)
Nun habe ich aber noch eine Frage:
Du deklarierst ja jetzt für beide Variablen das tk.StringVar(). Ich möchte jetzt, um in deinem Beispiel zu bleiben, in späteren Funktionen meiner Klasse mit der label_var Berechnungen durchführen. Kann ich das dann ohne weiteres machen? Also z.B. x = label_var * 2 oder solche Sachen eben.
Viele Grüße
AnyOne
Re: Zahlen mittels Entry Feld einlesen
Verfasst: Mittwoch 31. Oktober 2012, 11:55
von BlackJack
@AnyOne: Nein, das geht nicht. Das hättest Du auch sehr schnell heraus finden können. Ein Objekt vom Typ `Tkinter.StringVar` verhält sich weder wie eine Zeichenkette noch wie eine Zahl. Sondern eben wie eines vom Typ `StringVar`.
IMHO sind diese `Tkinter.*Var`-Typen auch nicht besonders oft benutzt. In den meisten Fällen, so wie hier, sieht mir das wie eine unnötige Indirektion aus. Ich würde die glaube ich nur einsetzen, wenn ich das „Observer”-Entwurfsmuster bräuchte, weil man an diese Typen „listener” binden kann, die bei verschiedenen Ereignissen, zum Beispiel Änderung des Wertes, aufgerufen werden.
Im Beispiel kommt man jedenfalls auch bequem ohne die beiden aus, in dem man `Entry.get()` und `Label.configure()` oder den Indexoperator auf dem `Label`-Exemplar verwendet.
Re: Zahlen mittels Entry Feld einlesen
Verfasst: Mittwoch 31. Oktober 2012, 12:06
von AnyOne
@BlackJack: Also das 'Entry.get()' habe ich, mit meiner Entry-Bezeichnung, auch schon probiert. Hier ist aber das Problem, dass ich ja in einer anderen Funktion der Klasse auf das Entry keinen direkten Zugriff mehr habe, oder verstehe ich da grad was falsch?
Re: Zahlen mittels Entry Feld einlesen
Verfasst: Mittwoch 31. Oktober 2012, 12:11
von BlackJack
@AnyOne: Ich verstehe die Frage nicht so ganz, denn mit den `StringVar`-Exemplaren hättest Du ja das gleiche Problem. Da scheinst Du es aber anscheinend hin zu bekommen? Wenn man in einer Methode auf ein Objekt zugreifen möchte, muss man es halt irgendwie zugänglich machen. In der Regel als Argument oder als Attribut auf dem Objekt auf dem die Methode existiert. Das ist in C++ doch auch nicht anders.
Re: Zahlen mittels Entry Feld einlesen
Verfasst: Mittwoch 31. Oktober 2012, 12:17
von wuf
Hi AnyOne
Hier ein Lösungsansatz:
Code: Alles auswählen
try:
#~~ For Python 2.x
import Tkinter as tk
except ImportError:
#~~ For Python 3.x
import tkinter as tk
def get_constant():
try:
# Einlesen der Konstante
constant = float(entry_var.get())
# Math operation
result = constant * 2.0
# Ausgabe des Resultats
label_var.set(result)
# Abfangen von Eingabefehlern
except ValueError as e:
print(e)
app_win = tk.Tk()
label_var = tk.StringVar()
entry_var = tk.StringVar()
constant_display = tk.Label(app_win, textvariable=label_var, relief='raised',
width=15, justify='left')
constant_display.pack(pady=5)
constant_entry = tk.Entry(app_win, textvariable=entry_var, bg='white')
constant_entry.pack(pady=5)
tk.Button(app_win, text="Konstante ins Label transferieren!",
command=get_constant).pack(pady=5)
app_win.mainloop()
Gruß wuf

Re: Zahlen mittels Entry Feld einlesen
Verfasst: Mittwoch 31. Oktober 2012, 15:37
von AnyOne
@BlackJack: StringVar() mag er nur, wenn ich auch wirklich einen String eingebe. Sobald da z.B. "1.8" eingegeben wird, meckert der Interpreter. Ich werde das Ganze jetzt einmal mit Klassenvariablen versuchen, die ich im Konstruktor definiere. So müsste ich diese Variablen ja den Funktionen der Klasse zugänglich machen können. Ich hoffe das Entry-Feld kann darauf dann zugreifen?
Code: Alles auswählen
class Blubb(object):
def __init__(self):
self.__entryVar = 0
...
def GUI(self):
...
testEntry = tk.Entry(self.GUI, textvariable = self.__entryVar)
...
def printEntry(self):
print self.__entryVar
So müsste doch dann das Zusammenspiel klappen, hoffe ich
@wuf: Wenn ich später zuhause bin, werde ich dein neues Beispiel durchdenken, vielen Dank schon einmal hierfür
Viele Grüße
AnyOne
Re: Zahlen mittels Entry Feld einlesen
Verfasst: Mittwoch 31. Oktober 2012, 18:53
von BlackJack
@AnyOne: Das kann nicht sein — man kann selbstverständlich auch die Zeichenkette '1.8' in einem `StringVar`-Objekt speichern:
Code: Alles auswählen
In [8]: import Tkinter as tk
In [9]: root = tk.Tk()
In [10]: sv = tk.StringVar(root, '1.8')
In [11]: sv.get()
Out[11]: '1.8'
Du möchtest keine Klassenvariablen sondern Instanzvariablen verwenden.
Das Beispiel kann so natürlich nicht funktionieren, weil das `textvariable`-Argument keine Zahl sondern zum Beispiel ein `StringVar`-Exemplar erwartet.
Die Namen halten sich nicht an
PEP 8 -- Style Guide for Python Code.
In `GUI()` übergibst Du `Entry` als erstes Argument die Methode, was nicht funktioniert.
Der doppelte Unterstrich bei `__entryVar` ist einer zu viel. Es ist sicher nicht davon auszugehen, dass es da bei abgeleiteten Klassen zu Namenskollisionen kommen wird.