tkinter.Entry, nur Zahlen oder String

Fragen zu Tkinter.
Antworten
Papp Nase
User
Beiträge: 139
Registriert: Dienstag 11. März 2014, 15:12

Hallo,

besteht bei dem Modul Entry() von tkinter die Möglichkeit, die Eingaben nur auf Zahlen zu beschränken? Oder muss ich das durch eine Funktion selbst schreiben, die den Eintrag überprüft und dann ggf. Buchstaben herausfiltert und löscht? Ich habe zwar schon im Internet gesucht, jedoch keine Möglichkeit gefunden, ob ich bei Entry(...) schon etwas reinschreiben kann. Ich habe gesehen, dass ich wieder eine Funktion aufrufen könnte, die reagiert, wenn eine Werteänderung in dem Entry-Feld erfolgt - dort bestünde dann auch die Möglichkeit. den Wert zu prüfen, aber vielleicht gibt es eine einfachere Variante?

Code: Alles auswählen

import tkinter
from functools import partial

def close_window(handler):
    handler.quit()

def main():
    print ("in main")
    mainwindow = tkinter.Tk()
    mainwindow.title("nasobeme")

    eingabefeld_integer=tkinter.Entry(mainwindow)
    eingabefeld_integer.pack()

    def werte_zeigen():
        print (eingabefeld_integer.get())

    beenden_button=tkinter.Button(mainwindow, text="Beenden", command=partial(close_window, mainwindow))
    beenden_button.pack()
    wertezeigen_button=tkinter.Button(mainwindow, text="Werte zeigen", command=werte_zeigen)
    wertezeigen_button.pack()

    mainwindow.mainloop()

if __name__ == '__main__':
    main()
bfm
User
Beiträge: 88
Registriert: Donnerstag 14. März 2013, 09:42

Hallo,

als ich anfangs mit tkinter "rumgespielt" hatte, hatte ich mal ein Beispielprogramm gemacht, wo jedes Tastenevent in einem Entry-Feld an eine Funktion gebunden hatte. In der Funktion müsste man dann prüfen, ob die Taste zulässig ist oder nicht und ggfs das letzte Zeichen halt wieder löschen.

stark vereinfacht:

eingabefeld.bind(<KeyPress>, funktion) ==> bei jeder gedrückten Taste die 'funktion' aufrufen

eingabefeld.delete('5',end) ==> lösche ab Zeichen 5 bis Ende

tkinter ist in dieser Hinsicht sehr einfach gehalten. Da muss man vieles selber machen. qt, gtk & Co bieten da sicher von Haus aus mehr und einfachere Möglichkeiten.

mfg
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Naja, ein bißchen was kann Tkinter schon. Siehe hier.
Ene Uran
User
Beiträge: 125
Registriert: Sonntag 17. September 2006, 20:14
Wohnort: Hollywood

Eine weitere Moeglichkeit ...

Code: Alles auswählen

# use Tkinter's simple dialogs to ask for input
# dialogs are askfloat, askinteger, and askstring
# mofified to work with Python2 and Python3

try:
    # for Python2
    import Tkinter as tk
    import tkMessageBox as tkmb
    import tkSimpleDialog as tksd
except ImportError:
    # for Python3
    import tkinter as tk
    import tkinter.messagebox as tkmb
    import tkinter.simpledialog as tksd

root = tk.Tk()
# show askstring dialog etc. without the Tkinter window
root.withdraw()

# (title, prompt)
name = tksd.askstring("Name", "Enter your name:")
cost = tksd.askfloat("Cost", "Amount you spend on food today:")
days = tksd.askinteger("Days", "How many more days are you staying here?")

sf = """\
Thank you %s.
You might spend  $%0.2f on food per day,
and you will be here for another %d days.
"""

msg = sf % (name, cost, days)
result = tkmb.showinfo("Oh dear!", msg)

# optional ...
#help(tksd)
#help(tkmb)
Zuletzt geändert von Anonymous am Sonntag 13. Juli 2014, 15:08, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Atomkraftwerkaktienbesitzer
Papp Nase
User
Beiträge: 139
Registriert: Dienstag 11. März 2014, 15:12

Vielen Dank für Eure Antworten, ich schaue mir die Beispiele von Euch gleich noch an, ich bin aber auf die Stringfunktionen is... gestoßen und habe mir hier ein kleines Testprogramm geschrieben und verschiedene Variableninhalte ausprobiert. Als letztes habe ich eine Zahl mit Punkt ausprobiert (also ein float/double ...)

Eine Funktion .isfloat() gibt es leider nicht. Gibt es eine "einfache" fertige Funktion wie .isdecimal() oder so, mit der ich auch testen kann, ob es ein Floatwert ist? Oder müsste ich mir dafür eine komplizierte Abfrage kreieren, die erst den String in zwei Teilstrings (vor - und nach dem Komma) unterteilt, dann diese beiden Einzelstrings testen, ob .isdecimal=True ist, um dann sicher zu sein, dass es ein Float ist?

Code: Alles auswählen

string_varialbe = "12568.566"

print ("isdigital: " + str(string_varialbe.isdigit()))
print ("isalpha: " + str(string_varialbe.isalpha()))
print ("isnumeric: " + str(string_varialbe.isnumeric()))
print ("isdecimal: " + str(string_varialbe.isdecimal()))
print ("isalnum: " + str(string_varialbe.isalnum()))
print ("isidentifier: " + str(string_varialbe.isidentifier()))
print ("islower: " + str(string_varialbe.islower()))
print ("isupper: " + str(string_varialbe.isupper()))
print ("isprintable: " + str(string_varialbe.isprintable()))
print ("isspace: " + str(string_varialbe.isspace()))
print ("istitle: " + str(string_varialbe.istitle()))
#print ("is: " + str(string_varialbe.is()))


im Internet habe ich nochwas gefunden - einmal mit try/except - dass klappt auch.
Mit isinstance (..., float) klappt es aber nicht. Warum geht isinstance so nicht? isinstance zeigt immer false an, egal ob ich "21.444" eingebe oder "12fd"?

Code: Alles auswählen

string_varialbe = "12fd"

print ("isdigital: " + str(string_varialbe.isdigit()))
print ("isalpha: " + str(string_varialbe.isalpha()))

...

try:
    abc=float(string_varialbe)
    print ("ist ein float")
except:
    print ("ist kein float")

print ("ist es ein float? " +  str(isinstance(string_varialbe, float))) #<<< das geht garnicht
BlackJack

@Papp Nase: Dazu muss man nichts kompliziertes schreiben, Du musst einfach nur die Zeichenkette in eine Gleitkommazahl wandeln. Mit `float()`. Das funktioniert, dann enthält die Zeichenkette eine gültige Darstellung einer Gleitkommazahl, oder das funktioniert nicht, dann eben nicht.

Edit: `isinstance()` testet den Typ des Wertes. Und völlig egal welche Zeichenfolge in einer Zeichenkette steht, es bleibt vom Typ her eine Zeichenkette.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Übrigens wünsche ich viel Spaß, wenn der Anwender die deutsche Schreibweise für Kommazahlen ("1.234,56") eingibt. Keine Ahnung, ob das Framework da von Haus aus etwas anbietet, oder ob man das selber auseinanderklamüsern muss.
BlackJack

@snafu: `locale.atof()` kann da helfen.
Papp Nase
User
Beiträge: 139
Registriert: Dienstag 11. März 2014, 15:12

Übrigens wünsche ich viel Spaß, wenn der Anwender die deutsche Schreibweise für Kommazahlen ("1.234,56") eingibt. Keine Ahnung, ob das Framework da von Haus aus etwas anbietet, oder ob man das selber auseinanderklamüsern muss.
Ach menno. Warum muss das alles so kompliziert und aufwendig sein :-(
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Nur, wenn man es selbst macht:

Code: Alles auswählen

In [8]: import locale

In [9]: locale.setlocale(locale.LC_NUMERIC, 'de_DE')
Out[9]: 'de_DE'

In [10]: locale.atof('1.234,56')
Out[10]: 1234.56

In [11]: locale.setlocale(locale.LC_NUMERIC, 'en_US')
Out[11]: 'en_US'

In [12]: locale.atof('1,234.56')
Out[12]: 1234.56

In [13]: locale.atof('abc')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-13-13d055265aff> in <module>()
----> 1 locale.atof('abc')

/usr/lib/python2.7/locale.pyc in atof(string, func)
    314         string = string.replace(dd, '.')
    315     #finally, parse the string
--> 316     return func(string)
    317 
    318 def atoi(str):

ValueError: could not convert string to float: abc
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

BlackJack hat geschrieben:@snafu: `locale.atof()` kann da helfen.
Hast recht. Hatte ich in dem Moment nicht auf dem Schirm.
Antworten