Seite 1 von 1
Eingabefeld bei verlassen prüfen
Verfasst: Samstag 14. September 2024, 13:39
von muekno
Hallo,
brauchen eine Tipp, ich will eingaben direkt bei Verlassen des entys prüfen und falls Bdingungen nicht erfüllt in Feld zurück.
Ich bin da auch vor Tagen über eine Möglichkeit gestolpert, die eine Meldung aufpoppen läst.
Finde das aber nicht mehr, suche schon ne Ewikeit bei Goole, aber irgendwie habe ich die falschen Schlüsselwörter.
Kann mir wer weiterhelfen, Danke
Re: Eingabefeld bei verlassen prüfen
Verfasst: Samstag 14. September 2024, 13:45
von sparrow
Python hat erst einmal keine Eingabefelder. Du musst schon verraten, was du verwendest um dir anzuzeigen.
Re: Eingabefeld bei verlassen prüfen
Verfasst: Samstag 14. September 2024, 15:33
von muekno
ich habe mit Tkinter ein Formular in dem es Eingabefelder gibt, beim verlassen soll jeweils die Eingabe auf gültige Werte überprüft werden. Die Überprüfung hab ich schon. Felder werden mit der folgenden Funktion erzeugt:
Code: Alles auswählen
# erstellt eingabe Felder, fields ist Parameter, Liste der Feldnamen
def makeform(root, fields):
eingaben = [] # array für die Werte
row = tk.Frame(root) # erstellt Zeile
row.pack(fill=tk.X, padx=5, pady=5) # zeigt an
for field in fields: # Schleife über Liste
tk.Label(row, width=10, text=field, anchor=tk.W).pack(side=tk.LEFT) # erzeugt, positioniert Feldname
entry = tk.Entry(row, width=10) # erzeugt Eingabefeld
entry.pack(side=tk.LEFT, expand=tk.YES, fill=tk.X) # zeigt an
eingaben.append((field, entry)) # werte in Rückgabe array
return eingaben # Rückgabe
Re: Eingabefeld bei verlassen prüfen
Verfasst: Samstag 14. September 2024, 16:11
von __blackjack__
@muekno: Schau Dir mal die `Entry`-Optionen `validate` und `validatecommand` an.
Sonstige Anmerkungen: Funktionen beschreibt man als DocString und nicht als Kommentar. Ansonsten sind da auch zu viele Kommentare die keinen Mehrwert über den Code bringen, weil sie einfach nur noch mal das beschreiben was da sowieso schon als Code steht. Kommentare sind nicht gedacht alles doppelt zu beschreiben, sondern Fragen zu klären die aus dem Code nicht offensichtlich zu beantworten sind.
Es gibt in Python auch Arrays. Das ist was anderes als Listen. Darum sollte man Listen nicht als Arrays bezeichnen.
Code: Alles auswählen
def make_form(master, field_names):
"""
Erstellt Eingabefelder in `master` mit den gegebenen `field_names` als
Beschriftungen.
:return: Paare von (Feldname, `Entry`).
"""
names_and_entries = []
row = tk.Frame(master)
row.pack(fill=tk.X, padx=5, pady=5)
for field_name in field_names:
tk.Label(row, width=10, text=field_name, anchor=tk.W).pack(
side=tk.LEFT
)
entry = tk.Entry(row, width=10)
entry.pack(side=tk.LEFT, expand=tk.YES, fill=tk.X)
names_and_entries.append((field_name, entry))
return names_and_entries
Re: Eingabefeld bei verlassen prüfen
Verfasst: Sonntag 15. September 2024, 11:25
von muekno
habe hier etwas gefunden
https://www.pythonguis.com/tutorials/in ... n-tkinter/
Aber trotzdem komme ich nicht wirklich weiter. Habe
den Code noch noch mal wesentlich gekürzt und quasi neu angefangen.
Code: Alles auswählen
"""
Formular zum Erstellen und Ändern der CAN Knoten Konfiguration
created 06.09.2024 by Rainer Müller-Knoche
"""
import tkinter as tk
from dataclasses import field
from math import trunc
# nächste Zeile ?
from tkinter.ttk import Label
from email.policy import default
from tkinter import messagebox, ttk, Button
def is_hex():
eingabe = node_id.get()
ok = False
if len(eingabe) != 4:
# print('wrong length')
return ok
if eingabe[0:2] != '0X':
# print('not 0X')
return ok
a = eingabe[2]
b = eingabe[3]
if ((a >= '0') and (a <= '9')) or ((a >= 'A') and (a <= 'F') and
(b >= '0') and (b <= '9')) or ((b >= 'A') and (b <= 'F')):
# print('passed')
ok = True
return ok
def printLabel(root, hinweis, attrib_color='white', attrib_size=12 ):
Hinweis = tk.Label(root, text=hinweis, anchor='w', fg=attrib_color, font=("Arial",attrib_size))
Hinweis.pack()
def main():
root = tk.Tk()
root.title('CAN_Config')
tk.Label(root, text='NodeID').grid(row=0, column=0)
tk.Label(root, text='GroupID').grid(row=0, column=2)
node_id = tk.Entry(
root,
width=20,
validatecommand=is_hex,
validate='focusout'
)
group_id = tk.Entry(root)
node_id.grid(row=0, column=1)
group_id.grid(row=0, column=3)
root.mainloop()
if __name__ == '__main__':
main()
wie bekomme ich die Eingabe in die Testroutine. Ja ich weiß die Prüfung ist Mist aber funktioniert
Danke für weitere Hilfe
Re: Eingabefeld bei verlassen prüfen
Verfasst: Sonntag 15. September 2024, 13:50
von muekno
Bin ein Stück weiter, habe den Beispielcode vom Link oben angepasst, aber im Gegensatz zum Beispielcode bekomme unresolved nodeID_entry
Aktueller Code
Code: Alles auswählen
"""
Formular zum Erstellen und Ändern der CAN Knoten Konfiguration
created 06.09.2024 by Rainer Müller-Knoche
"""
import tkinter as tk
from cProfile import label
from dataclasses import field
from math import trunc
from mmap import PROT_WRITE
# nächste Zeile ?
from tkinter.ttk import Label
from email.policy import default
from tkinter import messagebox, ttk, Button
from tokenize import group
def is_hex():
eingabe = nodeID_entry.get()
a = eingabe[2]
b = eingabe[3]
text = ''
if len(eingabe) != 4:
label.config(
text = 'wrong length',
fg = 'red'
)
return False
elif eingabe[0:2] != '0X':
label.config(
text = 'not 0X',
fg = 'red'
)
return False
elif ((a >= '0') and (a <= '9')) or ((a >= 'A') and (a <= 'F') and
(b >= '0') and (b <= '9')) or ((b >= 'A') and (b <= 'F')):
label.config(
text = 'passed',
fg = 'green'
)
return True
def printLabel(root, hinweis, attrib_color='white', attrib_size=12 ):
Hinweis = tk.Label(root, text=hinweis, anchor='w', fg=attrib_color, font=("Arial",attrib_size))
Hinweis.pack()
def main():
root = tk.Tk()
root.title('CAN_Config')
nodeID_label = ttk.Label(root, text='Node ID')
nodeID_label.grid(row=0, column=0, padx=5, pady=5)
nodeId_entry = ttk.Entry(
root,
width=35,
validatecommand=is_hex(),
validate='focusout'
)
nodeId_entry.grid(row=0, column=1, padx=5,pady=5)
groupID_label = ttk.Label(root, text='Node ID')
groupID_label.grid(row=0, column=2, padx=5, pady=5)
groupId_entry = ttk.Entry(root, width=35)
groupId_entry.grid(row=0, column=3, padx=5,pady=5)
if __name__ == '__main__':
main()
Verstehe nicht.
Grundsätzlich würde ich gerne den Wert an die Prüfunktion übergeben, da ich die noch öfter brauche
Vielen Dank für Hilfe
Re: Eingabefeld bei verlassen prüfen
Verfasst: Sonntag 15. September 2024, 14:06
von Sirius3
Na, mal wieder ein schönes Beispiel, wie viel Quatsch im Deckmantel eines "Tutorials" verbreitet wird.
validatecommand ist ein Tuple aus einem per registerCommand registrierten Callbacks und einem String, der angibt, welche Argumente dem Callback übergeben werden sollen:
https://tkdocs.com/shipman/entry-validation.html
Generell braucht man für GUIs Klassen, damit man nicht alle Widgets per Argument übergeben zu müssen.
Eingerückt wird immer mit 4 Leerzeichen nicht mit Tabs.
Variablennamen werden komplett klein geschrieben.
Die vielen Importe zeigen, dass Du irgendeine IDE benutzt, die das automatisch macht. Da ist viel Quatsch dabei, am besten alle Importe löschen, die Du nicht verstehst.
Re: Eingabefeld bei verlassen prüfen
Verfasst: Sonntag 15. September 2024, 15:00
von muekno
1. der Link ist uralt und wird ewig nicht mehr gepflegt.
2. meine IDE ist PcCharm
3. die imports sind noch aus früherem Code der aber in die falsche Richtung führt
4. tabs oder spaces sind egal, warum kann man das denn in der angeblich beliebtesten IDE so Einstellen. Mögen ja Puristen meinen das muss so sein.
5 das Problem ist, das meine Variable in derPrüfroutine nicht ankommt, weil main eine Funktion ist und die Variable damit lokal
früher hatte ich main einfach, dann kam hier einer der meinte müsste eine Funktion sein, weil man das so macht, bin ja als Pythonanfäger gerne gelehrig,.
6. wegen imports, und tabs und groß/kleinschtreibung rumnörgeln ist keine Hilfe
7. dieses alles kleinschreiben, macht den Code nicht gerade lesbarer.
8. Ich programiere zwar erst seit einigen Tagen mit Python GUI, habe aber schon diverse Python Scripts, auch größere geschrieben die alle laufen
9. Und programieren tue ich schon seit 50 Jahren, angefangen mit Z80 Assembler, ansonsten PHP, C, C++, Cobol etc.
Das musste mal gesagt werden
Re: Eingabefeld bei verlassen prüfen
Verfasst: Sonntag 15. September 2024, 15:21
von __blackjack__
@muekno: Tk ist auch uralt und an der API hat sich seit Mr. Shipmans Tod an der Stelle nicht wirklich etwas geändert was die Fragestellung hier betrifft. Der Link ist also relevant und enthält mehr Informationen als das Tutorial.
Tabs oder Leerzeichen ist nur in sofern egal als das überall *gleich* sein muss. Und da hat man sich halt auf vier Leerzeichen pro Ebene geeinigt. Kannst Du gerne anders machen, aber im Zweifelsfall bekommst Du dann keine Hilfe von Leuten die Deinen Code gerne mal ausprobieren würden, aber erst die Einrückung anpassen müssten um Veränderungen vorzunehmen.
Das Problem haben wir schon verstanden. Deswegen ja der Hinweis auf die Shipman-Dokumentation, so steht wie und welche Werte man in die Rückruffunktion als Argumente bekommen kann.
Ob klein_mit_unterstrichen oder mixedCase lesbarer ist, kann man wahrscheinlich nicht endgültig sagen. Es kommt halt darauf an, dass alle es gleich machen, damit man immer weiss wie es geschrieben wird, und nicht irgendwann auch mal zwei ”gleiche” Namen im selben Code existieren. *Das* ist dann wirklich verwirrend. Und Python-Konvention ist halt klein_mit_unterstrichen. Und Du scheinst da Probleme zu haben wenn ich mir anschaue das da sogar mixedCase_mit_unterstrichen gemischt wird und ID nicht einheitlich geschrieben wird.
Gerade bei so langen Zeiten wie 50 Jahre ist nicht zwingend ein Argument, weil die Erfahrung zeigt, das da einige Leute halt auch immer noch wie vor 50 Jahren programmieren, was auf, die können nicht gut programmieren, in modernen Sprachen hinaus läuft.
Re: Eingabefeld bei verlassen prüfen
Verfasst: Sonntag 15. September 2024, 16:05
von muekno
Danke für die Antwort
Ich bin zwar nicht mehr der Jüngste, habe aber kein Problem mit neuen Sprachen oder Methoden, bin da gerne lernfähig.
Einrücken mit Tabs oder Spaces, ich arbeite seit Ewigkeiten mit Tabs und zwar ausschließlich. Mix von Tabs und Spaces it absoluter Mist. und mit Tabs ist das Einrücken sichere. Gut die IDE hilft hier, aber mit Spaces hat man schnell ohne IDE ein Space zu wenig oder zu viel, je nach Font oder Schriftgröße fällt das nicht immer gleich auf und macht dann Ärger.
Groß/Kleinschreibung normalerweise mache ich das So erstesWort oder wenn länger erstesWortZweitesWort
Unterstriche verwende ich ehr so erstesWort_1, quasi als Index aber selten.
Dass hier ein Mix aus Groß/Kleinschreibung und Unterstrichen steht ist eher der Tatsache geschuldet, das ich den Code aus Beispielen zusammenkopiert und an meine Namen angepasst habe.
Mir geht es hier weniger um Schönheit oder Konventionen sonder darum dass erst mal etwas so funktioniert wie es sein soll und ich darauf aufbauen kann.
Ich habe auch kein Problem mich an klein mit Unterstrich bei Python zu halten, aber die Tabs will ich weiter nutzen.
Ansonsten, wie bekomme ich meinen Eingabewert in die Prüffunktion wenn main weiter ein Funktion ist.
1. ich könnte die Variable als Global definieren, widerstrebt mir.
2. Ich könnte 'def main()' auflösen, scheint aber nicht state of the art zu sein
3. ??
Hintergrund des ganzen ist, ich habe eine über 160 Byte große Konfigurationsdatei wo jedes Byte eine bestimmte Bedeutung hat. Die sieht z.B. so aus 0X03,0XFF,0X01,0X2A .....
die wir beim Upload auf den Mikrokontroller in echten Binärwerten in den Flash geschrieben und im Programm ausgewertet, das it stabil seit 5 Jahren.
Nun ist es aber lästig bei Änderungen, händisch diese Datei zu editieren und an der richtigen Stelle den Wert anzupassen.
Es gibt Werte wie nodeID oder groupID die direkt eingegeben werden müssen und es gibt viele (die meisten) in denen nur bestimmt Werte möglich sind, diese felder will ich aus DropDown Listen füllen, damit ist keine Fehleingabe möglich. Letzters hab ich schon, das funktioniert auch. Mir geht es momentan nur um die Eingeprüfung der händisch eingegeben Werte. Python hat als Eingabe nur Strings. Somit muß die Eingabe auf Gültigkeit geprüft werden. Auch soll diese ben sofort geschehen, bevor man ins nächste Eingabefeld kommt.
Gruß
Rainer
Re: Eingabefeld bei verlassen prüfen
Verfasst: Sonntag 15. September 2024, 16:54
von __blackjack__
@muekno: 1. und 2. sind das gleiche — ohne die `main()` sind die dort lokalen Variablen ja global.
Eine Lösung hat Sirius3 doch schon beschrieben und auf die Shipman-Dokumentation verwiesen. Man kann verschiedene Dinge angeben die dann der Validierungsfunktion als Argument(e) übergeben werden.
Wenn man diesen Mechanismus von Tk nicht verwenden möchte, könnte man noch mit `functools.partial()` arbeiten.