Seite 1 von 1

Geht validatecommand nicht?

Verfasst: Mittwoch 16. August 2017, 12:19
von Alfons Mittelmeyer
Der Benutzer soll nur gültige Zahlen in ein Entry eingeben können. Bei jedem Tastendruck soll das überprüft werden. Aber validatecommand funktioniert nicht richtig, denn wenn man da die Eingabe liest, ist diese noch gar nicht aktualisiert. Und auch mit einer Textvariablen funktioniert es nicht:

Code: Alles auswählen

# -*- coding: utf-8 -*-

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk

from functools import partial

class Application(tk.Tk):

    def __init__(self,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        # widget definitions ===================================
        self.entry = tk.Entry(self,name='#0_entry',validate='key')
        self.entry.pack()

        self.entry.insert(0,1)
        self.entry['validatecommand'] = partial(self.validate,self.entry)

    def validate(self,entry):
        correct = False
        print(self.entry.get())
        try:
            float(self.entry.get())
            correct = True
        except:
            pass
        return correct
        
if __name__ == '__main__':
    Application().mainloop()
Was kann man da tun? Stattdessen ein bind auf <Key> und dann einen Hack mit after?

Re: Geht validatecommand nicht?

Verfasst: Mittwoch 16. August 2017, 13:48
von BlackJack
@Alfons Mittelmeyer: Man könnte in der Referenzdoku von New Mexico Tech nachsehen wie man der Validierungsfunktion/-methode weitere Informationen mitgeben lassen kann: http://infohost.nmt.edu/tcc/help/pubs/t ... ation.html

Re: Geht validatecommand nicht?

Verfasst: Mittwoch 16. August 2017, 19:47
von Alfons Mittelmeyer
@BlackJack, danke. Ja, was man nocht nicht gemacht hat, weiß man eben manchmal nicht, dann wäre das wohl richtig, wenn es nur Integer sein sollen:

Code: Alles auswählen

# -*- coding: utf-8 -*-

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk

from functools import partial

class Application(tk.Tk):

    def __init__(self,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        # widget definitions ===================================
        self.entry = tk.Entry(self,validate='key')
        self.entry.pack()

        # already defined somewhere else ==========
        self.entry.variable = tk.StringVar()
        self.entry.variable.set(1)
        self.entry['textvariable'] = self.entry.variable
        # ==========================================

        validate_command = self.entry.register(self.validate)
        self.entry['vcmd'] = (validate_command,'%P')

        invalidate_command = self.entry.register(self.invalidate)
        self.entry['invcmd'] = (invalidate_command,'%s','%W')

    def validate(self,value_after):
        correct = False
        try:
            a = float(value_after)
            b = int(value_after)
            if a == b:
                correct = True
        except ValueError:
            pass
        return correct
        
    def invalidate(self,value_before,widget_name):
        widgdet = self.nametowidget(widget_name)
        widgdet.variable.set(value_before)

if __name__ == '__main__':
    Application().mainloop()
Aber ganz stimmt es noch nicht. Die erste Ziffer zu ändern bereitet Probleme. Aber leer sollte es auch nicht sein. Da muß man noch überlegen.

Re: Geht validatecommand nicht?

Verfasst: Mittwoch 16. August 2017, 20:26
von Alfons Mittelmeyer
Naja, da muss man wohl auch leer zulassen und später dann als 0 interpretieren:

Code: Alles auswählen

# -*- coding: utf-8 -*-

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk

from functools import partial

class Application(tk.Tk):

    def __init__(self,**kwargs):
        tk.Tk.__init__(self,**kwargs)
        # widget definitions ===================================
        self.entry = tk.Entry(self,validate='key')
        self.entry.pack()

        # already defined somewhere else ==========
        self.entry.variable = tk.StringVar()
        self.entry.variable.set(1)
        self.entry['textvariable'] = self.entry.variable
        # ==========================================

        validate_command = self.entry.register(self.validate)
        self.entry['vcmd'] = (validate_command,'%P')

        invalidate_command = self.entry.register(self.invalidate)
        self.entry['invcmd'] = (invalidate_command,'%s','%W')

    def validate(self,value_after):
        correct = False
        try:
            if not value_after:
                correct = True
            else:
                a = float(value_after)
                b = int(value_after)
                if a == b:
                    correct = True
        except ValueError:
            pass
        return correct
        
    def invalidate(self,value_before,widget_name):
        widgdet = self.nametowidget(widget_name)
        widgdet.variable.set(value_before)


if __name__ == '__main__':
    Application().mainloop()

Re: Geht validatecommand nicht?

Verfasst: Samstag 21. September 2019, 14:44
von Nummer_42O
Ich weiß nicht, was jetzt mit den letzten Paar Codeschnipseln passiert ist, die wir zu sehen bekamen, aber mein Lösungsvorschlag wäre folgender:

Code: Alles auswählen

# -*- coding: utf-8 -*-

try:
    from tkinter import *
except ImportError:
    from Tkinter import *

class Application(Tk):
    def __init__(self,**kwargs):
        Tk.__init__(self,**kwargs)
        self.entry=Entry(self,name='#0_entry',validate='key',vcmd=(self.register(self.validate),'%d','%P'),invcmd=self.bell)
        self.entry.pack()
        self.entry.insert(0,1)
    def validate(self,mode,value):
        if mode!=1: return False
        try:
            float(value)
            return True
        except: return False
        
if __name__ == '__main__':
    Application().mainloop()

Re: Geht validatecommand nicht?

Verfasst: Freitag 27. September 2019, 16:40
von Nummer_42O
Nummer_42O hat geschrieben: Samstag 21. September 2019, 14:44

Code: Alles auswählen

        if mode!=1: return False
Pardon, das müsste

Code: Alles auswählen

if mode!=1: return True
sein, da beim löschen ja nix überprüft werden muss, weil nix hinzu kommt.

Re: Geht validatecommand nicht?

Verfasst: Freitag 27. September 2019, 16:46
von __blackjack__
@Nummer_42O: Durch das löschen kann die Eingabe aber auch ungültig werden. "1e2" wird Beispielsweise ungültig wenn man die "1" oder die "2" entfernt, oder ".5" wird ungültig wenn man die "5" entfernt.