osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tkinter] question about correct use of validation


Il 16/01/19 08:51, Peter Otten ha scritto:

>      def make_ui(self):
>          ''' create user interface '''
> 
>          def vcmd(maxlength):
>              return self.parent.register(
>                  partial(self.maxlength_validate, maxlength=maxlength)
>              ), "%P"
> 
...

ok following your advice and that of Rick in the previous post, I 
developed 2 solutions, one without classes and one with classes. I write 
to you if you need someone:


1) solution with class

(taking a cue from here: 
http://effbot.org/zone/tkinter-entry-validate.htm - I wanted to reduce 
the code, I'm working on it)

from Tkinter import *


class View():
     ''' example for set max length of char in Entry widget.
                   -Class implantation-
     '''
     def __init__(self, parent):
         self.parent = parent
         self.make_ui()

     def make_ui(self):
         ''' create user interface '''
         self.id1_entry = self.make_entry(self.parent, maxlen=1).pack()
         self.id2_entry = self.make_entry(self.parent, maxlen=2).pack()
         self.id3_entry = self.make_entry(self.parent, maxlen=3).pack()
         self.id4_entry = self.make_entry(self.parent, maxlen=4).pack()
         self.id5_entry = self.make_entry(self.parent, maxlen=5).pack()

     def make_entry(self, parent, width=50, maxlen=30, 
highlightcolor='blue',
                    validate='key'):
         entry = MyEntry(parent, maxlen=maxlen)
         entry.configure(width=width, highlightcolor=highlightcolor)
         return entry


class ValidatingEntry(Entry):
     # base class for validating entry widgets
     def __init__(self, master, value="", **kw):
         apply(Entry.__init__, (self, master), kw)
         self.__value = value
         self.__variable = StringVar()
         self.__variable.set(value)
         self.__variable.trace("w", self.__callback)
         self.config(textvariable=self.__variable)
         self.configure(highlightcolor='blue')

     def __callback(self, *dummy):
         value = self.__variable.get()
         newvalue = self.validate(value)
         if newvalue is None:
             self.__variable.set(self.__value)
         elif newvalue != value:
             self.__value = newvalue
             self.__variable.set(newvalue)
         else:
             self.__value = value

     def validate(self, value):
         # override: return value, new value, or None if invalid
         return value


class MyEntry(ValidatingEntry):
     def __init__(self, master, value="", maxlen=None, **kw):
         self.maxlength = maxlen
         apply(ValidatingEntry.__init__, (self, master), kw)

     def validate(self, value):
         return value[:self.maxlength]

def run():
     root = Tk()
     root.title('test')
     View(root)
     root.mainloop()

if __name__ == "__main__":
     run()


------------------------------------------------------------

2) classless solution (part of your code)

from Tkinter import *

from functools import partial


class View():
     ''' example for set max length of char in Entry widget.
                   -Functions implantation-
     '''
     def __init__(self, parent):
         self.parent = parent
         self.make_ui()

     def make_ui(self):
         ''' create user interface '''
         self.id1_entry = self.make_entry(self.parent, maxlen=1).pack()
         self.id2_entry = self.make_entry(self.parent, maxlen=2).pack()
         self.id3_entry = self.make_entry(self.parent, maxlen=3).pack()
         self.id4_entry = self.make_entry(self.parent, maxlen=4).pack()
         self.id5_entry = self.make_entry(self.parent, maxlen=5).pack()

     def make_entry(self, parent, width=50, maxlen=30, 
highlightcolor='blue',
                    validate='key'):
         def vcmd(maxlength):
             return self.parent.register(partial(self.maxlength_validate,
                    maxlength=maxlength)), "%P"
         entry = Entry(parent)
         entry.configure(width=width, highlightcolor=highlightcolor,
                         validate='key', validatecommand=vcmd(maxlen))
         return entry

     def maxlength_validate(self, value, maxlength):
         return len(value) <= maxlength


def run():
     root = Tk()
     root.title('test')
     View(root)
     root.mainloop()

if __name__ == "__main__":
     run()


Thank you all