Geldbeträge in Entry erfassen
-
- User
- Beiträge: 5
- Registriert: Sonntag 20. Juni 2021, 18:02
Bin schon seit längerer Zeit auf der Suche nach einer Möglichkeit, das Format in einem Entry-Feld zu beeinflussen. Und zwar so, dass man nur Ziffern und ein Komma (oder Punkt) eingeben kann und die Nachkommastellen auf 2 begrenzt sind. Habe schon viel versucht (mit validate z.B.) - funktioniert aber alles nicht so richtig.
-
- User
- Beiträge: 5
- Registriert: Sonntag 20. Juni 2021, 18:02
Hier einer meiner Versuche - Code teilweise im Internet gefunden. Ich glaube, hiermit ist es schon fast ok. Wenn ich den Betrag in eine Datei speichern würde, müsste ich evtl. das Format anpassen? (z.B. aus der Eingabe "1,2" müsste dann "001,20" werden.
from tkinter import *
from tkinter import ttk
root=Tk()
import re
meldungs_text = StringVar()
def betrag_pruefen(newval, op):
meldungs_text.set('')
# valid = re.match('^[0-9]{3}(\,[0-9]{2})?$', newval) is not None
valid = re.match('^[0-9]+([,][0-9]{2})?$', newval) is not None
button1.state(['!disabled'] if valid else ['disabled'])
if op=='key':
ok_so_far = re.match('^[0-9\,]*$', newval) is not None and len(newval) <= 6
# ok_so_far = re.match('^[0-9][,]*$', newval) is not None and len(newval) <= 6
if not ok_so_far:
meldungs_text.set("nur Ziffern und Komma")
return ok_so_far
elif op=='focusout':
if not valid:
meldungs_text.set("nur Ziffern und Komma")
return valid
betrag_pruefen_wrapper = (root.register(betrag_pruefen), '%P', '%V')
betrag = StringVar()
frame1 = ttk.Frame(root)
frame1.grid(column=0, row=0)
ttk.Label(frame1, text='Betrag:').grid(column=0, row=1, padx=5, pady=5)
e_betrag = ttk.Entry(frame1, textvariable=betrag, validate='all', validatecommand=betrag_pruefen_wrapper)
e_betrag.grid(column=1, row=1, padx=5, pady=5)
button1 = ttk.Button(frame1, text="weiter")
button1.grid(column=2, row=1, padx=5, pady=5)
button1.state(['disabled'])
lb_meldung = ttk.Label(frame1, foreground='red', textvariable=meldungs_text)
lb_meldung.grid(column=1, row=2, padx=5, pady=5, sticky='w')
root.mainloop()
from tkinter import *
from tkinter import ttk
root=Tk()
import re
meldungs_text = StringVar()
def betrag_pruefen(newval, op):
meldungs_text.set('')
# valid = re.match('^[0-9]{3}(\,[0-9]{2})?$', newval) is not None
valid = re.match('^[0-9]+([,][0-9]{2})?$', newval) is not None
button1.state(['!disabled'] if valid else ['disabled'])
if op=='key':
ok_so_far = re.match('^[0-9\,]*$', newval) is not None and len(newval) <= 6
# ok_so_far = re.match('^[0-9][,]*$', newval) is not None and len(newval) <= 6
if not ok_so_far:
meldungs_text.set("nur Ziffern und Komma")
return ok_so_far
elif op=='focusout':
if not valid:
meldungs_text.set("nur Ziffern und Komma")
return valid
betrag_pruefen_wrapper = (root.register(betrag_pruefen), '%P', '%V')
betrag = StringVar()
frame1 = ttk.Frame(root)
frame1.grid(column=0, row=0)
ttk.Label(frame1, text='Betrag:').grid(column=0, row=1, padx=5, pady=5)
e_betrag = ttk.Entry(frame1, textvariable=betrag, validate='all', validatecommand=betrag_pruefen_wrapper)
e_betrag.grid(column=1, row=1, padx=5, pady=5)
button1 = ttk.Button(frame1, text="weiter")
button1.grid(column=2, row=1, padx=5, pady=5)
button1.state(['disabled'])
lb_meldung = ttk.Label(frame1, foreground='red', textvariable=meldungs_text)
lb_meldung.grid(column=1, row=2, padx=5, pady=5, sticky='w')
root.mainloop()
Alle Importe stehen ganz oben. Benutze keine *-Importe, weil damit verschleiert wird, woher welcher Name kommt.
Alles was eine Funktion braucht, muß sie auch über ihre Argumente bekommen. Benutze keine globalen Variablen.
Warum gibt es einen frame1 und einen button1, wo es doch insgesamt nicht mehr als einen gibt? Variablennamen müssen aussagekräftig sein, irgendwelche Nummern an Namen sind das nicht.
Wenn Du euro_betrag meinst, dann schreib das auch, und nicht e_betrag.
Und welches konkrete Problem hast Du jetzt? Die Validierung scheint doch zu funktionieren.
Alles was eine Funktion braucht, muß sie auch über ihre Argumente bekommen. Benutze keine globalen Variablen.
Warum gibt es einen frame1 und einen button1, wo es doch insgesamt nicht mehr als einen gibt? Variablennamen müssen aussagekräftig sein, irgendwelche Nummern an Namen sind das nicht.
Wenn Du euro_betrag meinst, dann schreib das auch, und nicht e_betrag.
Code: Alles auswählen
import re
import tkinter as tk
from tkinter import ttk
from functools import partial
def betrag_pruefen(weiter_button, meldungs_text, newval, op):
valid = re.match('^[0-9]+([,][0-9]{2})?$', newval) is not None
weiter_button.state(['!disabled' if valid else 'disabled'])
if op=='key':
valid = re.match('^[0-9\,]*$', newval) is not None and len(newval) <= 6
if not valid:
meldungs_text.set("nur Ziffern und Komma")
else:
meldungs_text.set('')
return valid
def main():
root = tk.Tk()
meldungstext = tk.StringVar(root)
betrag = tk.StringVar(root)
frame = ttk.Frame(root)
frame.grid(column=0, row=0)
weiter_button = ttk.Button(frame, text="weiter", state="disabled")
weiter_button.grid(column=2, row=1, padx=5, pady=5)
ttk.Label(frame, text='Betrag:').grid(column=0, row=1, padx=5, pady=5)
betrag_pruefen_wrapper = (root.register(partial(betrag_pruefen, weiter_button, meldungstext)), '%P', '%V')
euro_betrag = ttk.Entry(frame, textvariable=betrag, validate='all', validatecommand=betrag_pruefen_wrapper)
euro_betrag.grid(column=1, row=1, padx=5, pady=5)
ttk.Label(frame, foreground='red', textvariable=meldungstext).grid(column=1, row=2, padx=5, pady=5, sticky='w')
root.mainloop()
if __name__ == "__main__":
main()
-
- User
- Beiträge: 5
- Registriert: Sonntag 20. Juni 2021, 18:02
Hallo Sirius3, danke für die tollen Hinweise. Bin noch ziemlicher Neuling und diese Angaben haben mir sehr geholfen, python besser zu verstehen. Ich versuche immer wieder Beispiele im Internet zu finden. Dabei findet man oft die *-importe. Da ich noch nicht so firm bin, habe ich diese einfach immer übernommen. Das mit den Ziffern an den Variablennamen stammt aus meiner Programmiervergangenheit als Cobol-Programmierer, da war das ziemlich geläufig.
"Partial" kannte ich bisher noch nicht und werde ich mir genauer ansehen.
Nun zu meinen (kleinen) Problemen: wenn ich z.B. einen Wert ohne das Kommazeichen eingebe, sollte das nicht erlaubt sein. Evtl. könnte ich dann einbauen, dass dann beim Speichern der Zahl ein Komma angehängt wird, mit 2 Nullen. Aber ansonsten bin ich eigentlich doch schon zufrieden mit dieser Lösung.
"Partial" kannte ich bisher noch nicht und werde ich mir genauer ansehen.
Nun zu meinen (kleinen) Problemen: wenn ich z.B. einen Wert ohne das Kommazeichen eingebe, sollte das nicht erlaubt sein. Evtl. könnte ich dann einbauen, dass dann beim Speichern der Zahl ein Komma angehängt wird, mit 2 Nullen. Aber ansonsten bin ich eigentlich doch schon zufrieden mit dieser Lösung.