Ich habe ein Problem bei der Validierung der Spinbox-Eingabe. Ich habe einen Workaround unter diesem scheint zu arbeiten; es ist jedoch peinlich. Angenommen, dies ist kein Fehler, gibt es einen richtigen Weg, dies zu tun? Ich bin mit Anaconda Python 3.6 (tk 8.6) unter Windows 10.Python Tkinter Spinbox Validierung fehlgeschlagen
Das Problem ist, dass validate
-None
gesetzt, wenn Sie False
von der Validierungsfunktion, wenn der Wert in der Spinnbox Eintrag Rückkehr ist zwischen to
und from
. Dies geschieht nur, wenn Sie auf die Nach-oben- oder Nach-unten-Schaltfläche klicken und nicht, wenn Sie den Text direkt bearbeiten.
import tkinter as tk
class SpinboxGui:
def __init__(self):
self.root = tk.Tk()
vcmd = (self.root.register(self.validate_spin), '%W', '%P')
self.spin = tk.Spinbox(self.root, from_=0, to=50000)
self.spin.config(validate="key", validatecommand=vcmd)
self.spin.pack()
def validate_spin(self, name, nv):
try:
print(nv)
n = int(nv)
except:
return False
if n <= 15000:
return True
return False
if __name__ == "__main__":
SpinboxGui()
tk.mainloop()
Um zu reproduzieren, markieren Sie 0 und geben Sie 149999 ein. Klicken Sie dann ein paar Mal nach oben. Beachten Sie, dass der Validierungsbefehl nicht mehr aufgerufen wird. Die Ausgabe ist:
01
014
0149
01499
014999
0149999
15000
15001
nun nach dem docs, mit textVariable
und validateCommand
zusammen ist gefährlich; tatsächlich habe ich crashed Python/Tkinter in mehr als einer Hinsicht. In diesem Fall ist es jedoch egal, ob Sie textVariable
verwenden oder nicht; Das Problem ist das gleiche.
Eine mögliche Lösung könnte darin bestehen, die Optionen to
und from
in der Validierungsfunktion zu bearbeiten. Auch wenn das funktioniert, ist es für mich etwas problematisch, weil ich Spinbox-Werte mit einem eingebetteten Matplotlib-Plot synchronisiere. Ich müsste to
und from
berechnen und Einheiten für jeden Matplotlib Artist und Spinbox konvertieren.
Da Sie die textVariable
in der Validierungsfunktion nicht bearbeiten können, habe ich Folgendes herausgefunden. Vielleicht kann jemand das verbessern.
def __init__(self):
# http://stackoverflow.com/a/4140988/675216
vcmd= (self.root.register(self.validate_spin), '%W', '%P')
# Rest of code left out
self.spin.config(validate="key", validatecommand=vcmd)
self.spin.bind("<<ResetValidate>>", self.on_reset_validate)
def on_reset_validate(self, event):
# Turn validate back on and set textVariable
self.spin.config(validate="key")
def validate_spin(self, name, nv):
# Do validation ...
if not valid:
self.spin.event_generate("<<ResetValidate>>", when="tail")
return valid
Diese Aussage ist falsch: _ „Das Problem ist, dass validate auf None gesetzt ist, wenn Sie falsch von der Validierungsfunktion zurückkehren ...“ _ - die Funktion Validierung wird nicht auf 'None' gesetzt werden, nur weil Sie' False' zurückgeben. Die einzigen gültigen Rückgabewerte sind "True" und "False". Lesen und befolgen Sie den folgenden Hinweis: [Erstellen eines minimalen, vollständigen und überprüfbaren Beispiels] (http://www.stackoverflow.com/help/mcve) –
Es ist ein erheblicher Zeit- und Arbeitsaufwand, ein Problem zu reproduzieren. Es ist nicht so, dass ich zu faul bin, das zu tun. Ich dachte, dies könnte das beabsichtigte Verhalten der Spinbox sein. Ich wollte nicht die Zeit investieren, um ein nicht existierendes Problem zu jagen. Aber jetzt, wo ich informiert bin, ist es hier. – Todd