Interactively validating Entry widget content in tkinter












59















What is the recommended technique for interactively validating content in a tkinter Entry widget?



I've read the posts about using validate=True and validatecommand=command, and it appears that these features are limited by the fact that they get cleared if the validatecommand command updates the Entry widget's value.



Given this behavior, should we bind on the KeyPress, Cut, and Paste events and monitor/update our Entry widget's value through these events? (And other related events that I might have missed?)



Or should we forget interactive validation altogether and only validate on FocusOut events?










share|improve this question





























    59















    What is the recommended technique for interactively validating content in a tkinter Entry widget?



    I've read the posts about using validate=True and validatecommand=command, and it appears that these features are limited by the fact that they get cleared if the validatecommand command updates the Entry widget's value.



    Given this behavior, should we bind on the KeyPress, Cut, and Paste events and monitor/update our Entry widget's value through these events? (And other related events that I might have missed?)



    Or should we forget interactive validation altogether and only validate on FocusOut events?










    share|improve this question



























      59












      59








      59


      31






      What is the recommended technique for interactively validating content in a tkinter Entry widget?



      I've read the posts about using validate=True and validatecommand=command, and it appears that these features are limited by the fact that they get cleared if the validatecommand command updates the Entry widget's value.



      Given this behavior, should we bind on the KeyPress, Cut, and Paste events and monitor/update our Entry widget's value through these events? (And other related events that I might have missed?)



      Or should we forget interactive validation altogether and only validate on FocusOut events?










      share|improve this question
















      What is the recommended technique for interactively validating content in a tkinter Entry widget?



      I've read the posts about using validate=True and validatecommand=command, and it appears that these features are limited by the fact that they get cleared if the validatecommand command updates the Entry widget's value.



      Given this behavior, should we bind on the KeyPress, Cut, and Paste events and monitor/update our Entry widget's value through these events? (And other related events that I might have missed?)



      Or should we forget interactive validation altogether and only validate on FocusOut events?







      python validation tkinter textbox






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Aug 30 '17 at 13:33









      Paolo Forgia

      4,51262849




      4,51262849










      asked Nov 10 '10 at 1:24









      MalcolmMalcolm

      1,94243666




      1,94243666
























          5 Answers
          5






          active

          oldest

          votes


















          152














          The correct answer is, use the validatecommand attribute of the widget. Unfortunately this feature is severely under-documented in the Tkinter world, though it is quite sufficiently documented in the Tk world. Even though it's not documented well, it has everything you need to do validation without resorting to bindings or tracing variables, or modifying the widget from within the validation procedure.



          The trick is to know that you can have Tkinter pass in special values to your validate command. These values give you all the information you need to know to decide on whether the data is valid or not: the value prior to the edit, the value after the edit if the edit is valid, and several other bits of information. To use these, though, you need to do a little voodoo to get this information passed to your validate command.



          Note: it's important that the validation command returns either True or False. Anything else will cause the validation to be turned off for the widget.



          Here's an example that only allows lowercase (and prints all those funky values):



          import tkinter as tk  # python 3.x
          # import Tkinter as tk # python 2.x

          class Example(tk.Frame):

          def __init__(self, parent):
          tk.Frame.__init__(self, parent)

          # valid percent substitutions (from the Tk entry man page)
          # note: you only have to register the ones you need; this
          # example registers them all for illustrative purposes
          #
          # %d = Type of action (1=insert, 0=delete, -1 for others)
          # %i = index of char string to be inserted/deleted, or -1
          # %P = value of the entry if the edit is allowed
          # %s = value of entry prior to editing
          # %S = the text string being inserted or deleted, if any
          # %v = the type of validation that is currently set
          # %V = the type of validation that triggered the callback
          # (key, focusin, focusout, forced)
          # %W = the tk name of the widget

          vcmd = (self.register(self.onValidate),
          '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
          self.entry = tk.Entry(self, validate="key", validatecommand=vcmd)
          self.text = tk.Text(self, height=10, width=40)
          self.entry.pack(side="top", fill="x")
          self.text.pack(side="bottom", fill="both", expand=True)

          def onValidate(self, d, i, P, s, S, v, V, W):
          self.text.delete("1.0", "end")
          self.text.insert("end","OnValidate:n")
          self.text.insert("end","d='%s'n" % d)
          self.text.insert("end","i='%s'n" % i)
          self.text.insert("end","P='%s'n" % P)
          self.text.insert("end","s='%s'n" % s)
          self.text.insert("end","S='%s'n" % S)
          self.text.insert("end","v='%s'n" % v)
          self.text.insert("end","V='%s'n" % V)
          self.text.insert("end","W='%s'n" % W)

          # Disallow anything but lowercase letters
          if S == S.lower():
          return True
          else:
          self.bell()
          return False

          if __name__ == "__main__":
          root = tk.Tk()
          Example(root).pack(fill="both", expand=True)
          root.mainloop()





          share|improve this answer





















          • 12





            This is the right way to do it. It addresses the problems I found when I tried to get jmeyer10's answer working. This one example provides superior documentation to validate compared to what I can find elsewhere. I wish I could give this 5 votes.

            – Steven Rumbalski
            Nov 10 '10 at 3:34








          • 2





            WOW! I agree with Steven - this is the type of reply that deserves more than one vote. You should write a book on Tkinter (and you've already posted enough solutions to make that a multi-volume series). Thank you!!!

            – Malcolm
            Nov 10 '10 at 13:31











          • As a side note: I'm blown away by the power of Tkinter. Its gotten a bad wrap for many years, but with the new support for native themes (ttk) and explanations of its hidden power powers by experts like Bryan Oakley, this GUI framework can hold its own against the likes of wxPython, pyQT, and others.

            – Malcolm
            Nov 10 '10 at 13:35






          • 2





            Thanks for the example. It's worth noting that the validatecommand MUST return a boolean (only True and False). If not, the validation will be removed.

            – Dave Bacher
            Jun 19 '12 at 5:50






          • 2





            I think this page should be brought to the fore.

            – Right leg
            Sep 8 '17 at 13:57



















          7














          Use a Tkinter.StringVar to track the value of the Entry widget. You can validate the value of the StringVar by setting a trace on it.



          Here's a short working program that accepts only valid floats in the Entry widget.



          from Tkinter import *
          root = Tk()
          sv = StringVar()

          def validate_float(var):
          new_value = var.get()
          try:
          new_value == '' or float(new_value)
          validate.old_value = new_value
          except:
          var.set(validate.old_value)
          validate.old_value = ''

          # trace wants a callback with nearly useless parameters, fixing with lambda.
          sv.trace('w', lambda nm, idx, mode, var=sv: validate_float(var))
          ent = Entry(root, textvariable=sv)
          ent.pack()

          root.mainloop()





          share|improve this answer
























          • Thanks for your post. I enjoyed seeing the Tkinter StringVar .trace() method in use.

            – Malcolm
            Nov 10 '10 at 13:38



















          6














          After studying and experimenting with Bryan's code, I produced a minimal version of input validation. The following code will put up an Entry box and only accept numeric digits.



          from tkinter import *

          root = Tk()

          def testVal(inStr,acttyp):
          if acttyp == '1': #insert
          if not inStr.isdigit():
          return False
          return True

          entry = Entry(root, validate="key")
          entry['validatecommand'] = (entry.register(testVal),'%P','%d')
          entry.pack()

          root.mainloop()


          Perhaps I should add that I am still learning Python and I will gladly accept any and all comments/suggestions.






          share|improve this answer


























          • Generally people use entry.configure(validatecommand=...) and write test_val instead of testVal, but this is a good, simple example.

            – wizzwizz4
            Aug 12 '18 at 14:58



















          2














          While studying Bryan Oakley's answer, something told me that a far more general solution could be developed. The following example introduces a mode enumeration, a type dictionary, and a setup function for validation purposes. See line 48 for example usage and a demonstration of its simplicity.



          #! /usr/bin/env python3
          # https://stackoverflow.com/questions/4140437
          import enum
          import inspect
          import tkinter
          from tkinter.constants import *


          Mode = enum.Enum('Mode', 'none key focus focusin focusout all')
          CAST = dict(d=int, i=int, P=str, s=str, S=str,
          v=Mode.__getitem__, V=Mode.__getitem__, W=str)


          def on_validate(widget, mode, validator):
          # http://www.tcl.tk/man/tcl/TkCmd/ttk_entry.htm#M39
          if mode not in Mode:
          raise ValueError('mode not recognized')
          parameters = inspect.signature(validator).parameters
          if not set(parameters).issubset(CAST):
          raise ValueError('validator arguments not recognized')
          casts = tuple(map(CAST.__getitem__, parameters))
          widget.configure(validate=mode.name, validatecommand=[widget.register(
          lambda *args: bool(validator(*(cast(arg) for cast, arg in zip(
          casts, args)))))]+['%' + parameter for parameter in parameters])


          class Example(tkinter.Frame):

          @classmethod
          def main(cls):
          tkinter.NoDefaultRoot()
          root = tkinter.Tk()
          root.title('Validation Example')
          cls(root).grid(sticky=NSEW)
          root.grid_rowconfigure(0, weight=1)
          root.grid_columnconfigure(0, weight=1)
          root.mainloop()

          def __init__(self, master, **kw):
          super().__init__(master, **kw)
          self.entry = tkinter.Entry(self)
          self.text = tkinter.Text(self, height=15, width=50,
          wrap=WORD, state=DISABLED)
          self.entry.grid(row=0, column=0, sticky=NSEW)
          self.text.grid(row=1, column=0, sticky=NSEW)
          self.grid_rowconfigure(1, weight=1)
          self.grid_columnconfigure(0, weight=1)
          on_validate(self.entry, Mode.key, self.validator)

          def validator(self, d, i, P, s, S, v, V, W):
          self.text['state'] = NORMAL
          self.text.delete(1.0, END)
          self.text.insert(END, 'd = {!r}ni = {!r}nP = {!r}ns = {!r}n'
          'S = {!r}nv = {!r}nV = {!r}nW = {!r}'
          .format(d, i, P, s, S, v, V, W))
          self.text['state'] = DISABLED
          return not S.isupper()


          if __name__ == '__main__':
          Example.main()





          share|improve this answer

































            1














            Bryan's answer is correct, however no one mentioned the 'invalidcommand' attribute of the tkinter widget.



            A good explanation is here:
            http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/entry-validation.html



            Text copy/pasted in case of broken link



            The Entry widget also supports an invalidcommand option that specifies a callback function that is called whenever the validatecommand returns False. This command may modify the text in the widget by using the .set() method on the widget's associated textvariable. Setting up this option works the same as setting up the validatecommand. You must use the .register() method to wrap your Python function; this method returns the name of the wrapped function as a string. Then you will pass as the value of the invalidcommand option either that string, or as the first element of a tuple containing substitution codes.



            Note:
            There is only one thing that I cannot figure out how to do: If you add validation to an entry, and the user selects a portion of the text and types a new value, there is no way to capture the original value and reset the entry. Here's an example




            1. Entry is designed to only accept integers by implementing 'validatecommand'

            2. User enters 1234567

            3. User selects '345' and presses 'j'. This is registered as two actions: deletion of '345', and insertion of 'j'. Tkinter ignores the deletion and acts only on the insertion of 'j'. 'validatecommand' returns False, and the values passed to the 'invalidcommand' function are as follows: %d=1, %i=2, %P=12j67, %s=1267, %S=j

            4. If the code does not implement an 'invalidcommand' function, the 'validatecommand' function will reject the 'j' and the result will be 1267. If the code does implement an 'invalidcommand' function, there is no way to recover the original 1234567.






            share|improve this answer

























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4140437%2finteractively-validating-entry-widget-content-in-tkinter%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              5 Answers
              5






              active

              oldest

              votes








              5 Answers
              5






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              152














              The correct answer is, use the validatecommand attribute of the widget. Unfortunately this feature is severely under-documented in the Tkinter world, though it is quite sufficiently documented in the Tk world. Even though it's not documented well, it has everything you need to do validation without resorting to bindings or tracing variables, or modifying the widget from within the validation procedure.



              The trick is to know that you can have Tkinter pass in special values to your validate command. These values give you all the information you need to know to decide on whether the data is valid or not: the value prior to the edit, the value after the edit if the edit is valid, and several other bits of information. To use these, though, you need to do a little voodoo to get this information passed to your validate command.



              Note: it's important that the validation command returns either True or False. Anything else will cause the validation to be turned off for the widget.



              Here's an example that only allows lowercase (and prints all those funky values):



              import tkinter as tk  # python 3.x
              # import Tkinter as tk # python 2.x

              class Example(tk.Frame):

              def __init__(self, parent):
              tk.Frame.__init__(self, parent)

              # valid percent substitutions (from the Tk entry man page)
              # note: you only have to register the ones you need; this
              # example registers them all for illustrative purposes
              #
              # %d = Type of action (1=insert, 0=delete, -1 for others)
              # %i = index of char string to be inserted/deleted, or -1
              # %P = value of the entry if the edit is allowed
              # %s = value of entry prior to editing
              # %S = the text string being inserted or deleted, if any
              # %v = the type of validation that is currently set
              # %V = the type of validation that triggered the callback
              # (key, focusin, focusout, forced)
              # %W = the tk name of the widget

              vcmd = (self.register(self.onValidate),
              '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
              self.entry = tk.Entry(self, validate="key", validatecommand=vcmd)
              self.text = tk.Text(self, height=10, width=40)
              self.entry.pack(side="top", fill="x")
              self.text.pack(side="bottom", fill="both", expand=True)

              def onValidate(self, d, i, P, s, S, v, V, W):
              self.text.delete("1.0", "end")
              self.text.insert("end","OnValidate:n")
              self.text.insert("end","d='%s'n" % d)
              self.text.insert("end","i='%s'n" % i)
              self.text.insert("end","P='%s'n" % P)
              self.text.insert("end","s='%s'n" % s)
              self.text.insert("end","S='%s'n" % S)
              self.text.insert("end","v='%s'n" % v)
              self.text.insert("end","V='%s'n" % V)
              self.text.insert("end","W='%s'n" % W)

              # Disallow anything but lowercase letters
              if S == S.lower():
              return True
              else:
              self.bell()
              return False

              if __name__ == "__main__":
              root = tk.Tk()
              Example(root).pack(fill="both", expand=True)
              root.mainloop()





              share|improve this answer





















              • 12





                This is the right way to do it. It addresses the problems I found when I tried to get jmeyer10's answer working. This one example provides superior documentation to validate compared to what I can find elsewhere. I wish I could give this 5 votes.

                – Steven Rumbalski
                Nov 10 '10 at 3:34








              • 2





                WOW! I agree with Steven - this is the type of reply that deserves more than one vote. You should write a book on Tkinter (and you've already posted enough solutions to make that a multi-volume series). Thank you!!!

                – Malcolm
                Nov 10 '10 at 13:31











              • As a side note: I'm blown away by the power of Tkinter. Its gotten a bad wrap for many years, but with the new support for native themes (ttk) and explanations of its hidden power powers by experts like Bryan Oakley, this GUI framework can hold its own against the likes of wxPython, pyQT, and others.

                – Malcolm
                Nov 10 '10 at 13:35






              • 2





                Thanks for the example. It's worth noting that the validatecommand MUST return a boolean (only True and False). If not, the validation will be removed.

                – Dave Bacher
                Jun 19 '12 at 5:50






              • 2





                I think this page should be brought to the fore.

                – Right leg
                Sep 8 '17 at 13:57
















              152














              The correct answer is, use the validatecommand attribute of the widget. Unfortunately this feature is severely under-documented in the Tkinter world, though it is quite sufficiently documented in the Tk world. Even though it's not documented well, it has everything you need to do validation without resorting to bindings or tracing variables, or modifying the widget from within the validation procedure.



              The trick is to know that you can have Tkinter pass in special values to your validate command. These values give you all the information you need to know to decide on whether the data is valid or not: the value prior to the edit, the value after the edit if the edit is valid, and several other bits of information. To use these, though, you need to do a little voodoo to get this information passed to your validate command.



              Note: it's important that the validation command returns either True or False. Anything else will cause the validation to be turned off for the widget.



              Here's an example that only allows lowercase (and prints all those funky values):



              import tkinter as tk  # python 3.x
              # import Tkinter as tk # python 2.x

              class Example(tk.Frame):

              def __init__(self, parent):
              tk.Frame.__init__(self, parent)

              # valid percent substitutions (from the Tk entry man page)
              # note: you only have to register the ones you need; this
              # example registers them all for illustrative purposes
              #
              # %d = Type of action (1=insert, 0=delete, -1 for others)
              # %i = index of char string to be inserted/deleted, or -1
              # %P = value of the entry if the edit is allowed
              # %s = value of entry prior to editing
              # %S = the text string being inserted or deleted, if any
              # %v = the type of validation that is currently set
              # %V = the type of validation that triggered the callback
              # (key, focusin, focusout, forced)
              # %W = the tk name of the widget

              vcmd = (self.register(self.onValidate),
              '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
              self.entry = tk.Entry(self, validate="key", validatecommand=vcmd)
              self.text = tk.Text(self, height=10, width=40)
              self.entry.pack(side="top", fill="x")
              self.text.pack(side="bottom", fill="both", expand=True)

              def onValidate(self, d, i, P, s, S, v, V, W):
              self.text.delete("1.0", "end")
              self.text.insert("end","OnValidate:n")
              self.text.insert("end","d='%s'n" % d)
              self.text.insert("end","i='%s'n" % i)
              self.text.insert("end","P='%s'n" % P)
              self.text.insert("end","s='%s'n" % s)
              self.text.insert("end","S='%s'n" % S)
              self.text.insert("end","v='%s'n" % v)
              self.text.insert("end","V='%s'n" % V)
              self.text.insert("end","W='%s'n" % W)

              # Disallow anything but lowercase letters
              if S == S.lower():
              return True
              else:
              self.bell()
              return False

              if __name__ == "__main__":
              root = tk.Tk()
              Example(root).pack(fill="both", expand=True)
              root.mainloop()





              share|improve this answer





















              • 12





                This is the right way to do it. It addresses the problems I found when I tried to get jmeyer10's answer working. This one example provides superior documentation to validate compared to what I can find elsewhere. I wish I could give this 5 votes.

                – Steven Rumbalski
                Nov 10 '10 at 3:34








              • 2





                WOW! I agree with Steven - this is the type of reply that deserves more than one vote. You should write a book on Tkinter (and you've already posted enough solutions to make that a multi-volume series). Thank you!!!

                – Malcolm
                Nov 10 '10 at 13:31











              • As a side note: I'm blown away by the power of Tkinter. Its gotten a bad wrap for many years, but with the new support for native themes (ttk) and explanations of its hidden power powers by experts like Bryan Oakley, this GUI framework can hold its own against the likes of wxPython, pyQT, and others.

                – Malcolm
                Nov 10 '10 at 13:35






              • 2





                Thanks for the example. It's worth noting that the validatecommand MUST return a boolean (only True and False). If not, the validation will be removed.

                – Dave Bacher
                Jun 19 '12 at 5:50






              • 2





                I think this page should be brought to the fore.

                – Right leg
                Sep 8 '17 at 13:57














              152












              152








              152







              The correct answer is, use the validatecommand attribute of the widget. Unfortunately this feature is severely under-documented in the Tkinter world, though it is quite sufficiently documented in the Tk world. Even though it's not documented well, it has everything you need to do validation without resorting to bindings or tracing variables, or modifying the widget from within the validation procedure.



              The trick is to know that you can have Tkinter pass in special values to your validate command. These values give you all the information you need to know to decide on whether the data is valid or not: the value prior to the edit, the value after the edit if the edit is valid, and several other bits of information. To use these, though, you need to do a little voodoo to get this information passed to your validate command.



              Note: it's important that the validation command returns either True or False. Anything else will cause the validation to be turned off for the widget.



              Here's an example that only allows lowercase (and prints all those funky values):



              import tkinter as tk  # python 3.x
              # import Tkinter as tk # python 2.x

              class Example(tk.Frame):

              def __init__(self, parent):
              tk.Frame.__init__(self, parent)

              # valid percent substitutions (from the Tk entry man page)
              # note: you only have to register the ones you need; this
              # example registers them all for illustrative purposes
              #
              # %d = Type of action (1=insert, 0=delete, -1 for others)
              # %i = index of char string to be inserted/deleted, or -1
              # %P = value of the entry if the edit is allowed
              # %s = value of entry prior to editing
              # %S = the text string being inserted or deleted, if any
              # %v = the type of validation that is currently set
              # %V = the type of validation that triggered the callback
              # (key, focusin, focusout, forced)
              # %W = the tk name of the widget

              vcmd = (self.register(self.onValidate),
              '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
              self.entry = tk.Entry(self, validate="key", validatecommand=vcmd)
              self.text = tk.Text(self, height=10, width=40)
              self.entry.pack(side="top", fill="x")
              self.text.pack(side="bottom", fill="both", expand=True)

              def onValidate(self, d, i, P, s, S, v, V, W):
              self.text.delete("1.0", "end")
              self.text.insert("end","OnValidate:n")
              self.text.insert("end","d='%s'n" % d)
              self.text.insert("end","i='%s'n" % i)
              self.text.insert("end","P='%s'n" % P)
              self.text.insert("end","s='%s'n" % s)
              self.text.insert("end","S='%s'n" % S)
              self.text.insert("end","v='%s'n" % v)
              self.text.insert("end","V='%s'n" % V)
              self.text.insert("end","W='%s'n" % W)

              # Disallow anything but lowercase letters
              if S == S.lower():
              return True
              else:
              self.bell()
              return False

              if __name__ == "__main__":
              root = tk.Tk()
              Example(root).pack(fill="both", expand=True)
              root.mainloop()





              share|improve this answer















              The correct answer is, use the validatecommand attribute of the widget. Unfortunately this feature is severely under-documented in the Tkinter world, though it is quite sufficiently documented in the Tk world. Even though it's not documented well, it has everything you need to do validation without resorting to bindings or tracing variables, or modifying the widget from within the validation procedure.



              The trick is to know that you can have Tkinter pass in special values to your validate command. These values give you all the information you need to know to decide on whether the data is valid or not: the value prior to the edit, the value after the edit if the edit is valid, and several other bits of information. To use these, though, you need to do a little voodoo to get this information passed to your validate command.



              Note: it's important that the validation command returns either True or False. Anything else will cause the validation to be turned off for the widget.



              Here's an example that only allows lowercase (and prints all those funky values):



              import tkinter as tk  # python 3.x
              # import Tkinter as tk # python 2.x

              class Example(tk.Frame):

              def __init__(self, parent):
              tk.Frame.__init__(self, parent)

              # valid percent substitutions (from the Tk entry man page)
              # note: you only have to register the ones you need; this
              # example registers them all for illustrative purposes
              #
              # %d = Type of action (1=insert, 0=delete, -1 for others)
              # %i = index of char string to be inserted/deleted, or -1
              # %P = value of the entry if the edit is allowed
              # %s = value of entry prior to editing
              # %S = the text string being inserted or deleted, if any
              # %v = the type of validation that is currently set
              # %V = the type of validation that triggered the callback
              # (key, focusin, focusout, forced)
              # %W = the tk name of the widget

              vcmd = (self.register(self.onValidate),
              '%d', '%i', '%P', '%s', '%S', '%v', '%V', '%W')
              self.entry = tk.Entry(self, validate="key", validatecommand=vcmd)
              self.text = tk.Text(self, height=10, width=40)
              self.entry.pack(side="top", fill="x")
              self.text.pack(side="bottom", fill="both", expand=True)

              def onValidate(self, d, i, P, s, S, v, V, W):
              self.text.delete("1.0", "end")
              self.text.insert("end","OnValidate:n")
              self.text.insert("end","d='%s'n" % d)
              self.text.insert("end","i='%s'n" % i)
              self.text.insert("end","P='%s'n" % P)
              self.text.insert("end","s='%s'n" % s)
              self.text.insert("end","S='%s'n" % S)
              self.text.insert("end","v='%s'n" % v)
              self.text.insert("end","V='%s'n" % V)
              self.text.insert("end","W='%s'n" % W)

              # Disallow anything but lowercase letters
              if S == S.lower():
              return True
              else:
              self.bell()
              return False

              if __name__ == "__main__":
              root = tk.Tk()
              Example(root).pack(fill="both", expand=True)
              root.mainloop()






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jan 19 '17 at 13:09

























              answered Nov 10 '10 at 3:29









              Bryan OakleyBryan Oakley

              214k21255418




              214k21255418








              • 12





                This is the right way to do it. It addresses the problems I found when I tried to get jmeyer10's answer working. This one example provides superior documentation to validate compared to what I can find elsewhere. I wish I could give this 5 votes.

                – Steven Rumbalski
                Nov 10 '10 at 3:34








              • 2





                WOW! I agree with Steven - this is the type of reply that deserves more than one vote. You should write a book on Tkinter (and you've already posted enough solutions to make that a multi-volume series). Thank you!!!

                – Malcolm
                Nov 10 '10 at 13:31











              • As a side note: I'm blown away by the power of Tkinter. Its gotten a bad wrap for many years, but with the new support for native themes (ttk) and explanations of its hidden power powers by experts like Bryan Oakley, this GUI framework can hold its own against the likes of wxPython, pyQT, and others.

                – Malcolm
                Nov 10 '10 at 13:35






              • 2





                Thanks for the example. It's worth noting that the validatecommand MUST return a boolean (only True and False). If not, the validation will be removed.

                – Dave Bacher
                Jun 19 '12 at 5:50






              • 2





                I think this page should be brought to the fore.

                – Right leg
                Sep 8 '17 at 13:57














              • 12





                This is the right way to do it. It addresses the problems I found when I tried to get jmeyer10's answer working. This one example provides superior documentation to validate compared to what I can find elsewhere. I wish I could give this 5 votes.

                – Steven Rumbalski
                Nov 10 '10 at 3:34








              • 2





                WOW! I agree with Steven - this is the type of reply that deserves more than one vote. You should write a book on Tkinter (and you've already posted enough solutions to make that a multi-volume series). Thank you!!!

                – Malcolm
                Nov 10 '10 at 13:31











              • As a side note: I'm blown away by the power of Tkinter. Its gotten a bad wrap for many years, but with the new support for native themes (ttk) and explanations of its hidden power powers by experts like Bryan Oakley, this GUI framework can hold its own against the likes of wxPython, pyQT, and others.

                – Malcolm
                Nov 10 '10 at 13:35






              • 2





                Thanks for the example. It's worth noting that the validatecommand MUST return a boolean (only True and False). If not, the validation will be removed.

                – Dave Bacher
                Jun 19 '12 at 5:50






              • 2





                I think this page should be brought to the fore.

                – Right leg
                Sep 8 '17 at 13:57








              12




              12





              This is the right way to do it. It addresses the problems I found when I tried to get jmeyer10's answer working. This one example provides superior documentation to validate compared to what I can find elsewhere. I wish I could give this 5 votes.

              – Steven Rumbalski
              Nov 10 '10 at 3:34







              This is the right way to do it. It addresses the problems I found when I tried to get jmeyer10's answer working. This one example provides superior documentation to validate compared to what I can find elsewhere. I wish I could give this 5 votes.

              – Steven Rumbalski
              Nov 10 '10 at 3:34






              2




              2





              WOW! I agree with Steven - this is the type of reply that deserves more than one vote. You should write a book on Tkinter (and you've already posted enough solutions to make that a multi-volume series). Thank you!!!

              – Malcolm
              Nov 10 '10 at 13:31





              WOW! I agree with Steven - this is the type of reply that deserves more than one vote. You should write a book on Tkinter (and you've already posted enough solutions to make that a multi-volume series). Thank you!!!

              – Malcolm
              Nov 10 '10 at 13:31













              As a side note: I'm blown away by the power of Tkinter. Its gotten a bad wrap for many years, but with the new support for native themes (ttk) and explanations of its hidden power powers by experts like Bryan Oakley, this GUI framework can hold its own against the likes of wxPython, pyQT, and others.

              – Malcolm
              Nov 10 '10 at 13:35





              As a side note: I'm blown away by the power of Tkinter. Its gotten a bad wrap for many years, but with the new support for native themes (ttk) and explanations of its hidden power powers by experts like Bryan Oakley, this GUI framework can hold its own against the likes of wxPython, pyQT, and others.

              – Malcolm
              Nov 10 '10 at 13:35




              2




              2





              Thanks for the example. It's worth noting that the validatecommand MUST return a boolean (only True and False). If not, the validation will be removed.

              – Dave Bacher
              Jun 19 '12 at 5:50





              Thanks for the example. It's worth noting that the validatecommand MUST return a boolean (only True and False). If not, the validation will be removed.

              – Dave Bacher
              Jun 19 '12 at 5:50




              2




              2





              I think this page should be brought to the fore.

              – Right leg
              Sep 8 '17 at 13:57





              I think this page should be brought to the fore.

              – Right leg
              Sep 8 '17 at 13:57













              7














              Use a Tkinter.StringVar to track the value of the Entry widget. You can validate the value of the StringVar by setting a trace on it.



              Here's a short working program that accepts only valid floats in the Entry widget.



              from Tkinter import *
              root = Tk()
              sv = StringVar()

              def validate_float(var):
              new_value = var.get()
              try:
              new_value == '' or float(new_value)
              validate.old_value = new_value
              except:
              var.set(validate.old_value)
              validate.old_value = ''

              # trace wants a callback with nearly useless parameters, fixing with lambda.
              sv.trace('w', lambda nm, idx, mode, var=sv: validate_float(var))
              ent = Entry(root, textvariable=sv)
              ent.pack()

              root.mainloop()





              share|improve this answer
























              • Thanks for your post. I enjoyed seeing the Tkinter StringVar .trace() method in use.

                – Malcolm
                Nov 10 '10 at 13:38
















              7














              Use a Tkinter.StringVar to track the value of the Entry widget. You can validate the value of the StringVar by setting a trace on it.



              Here's a short working program that accepts only valid floats in the Entry widget.



              from Tkinter import *
              root = Tk()
              sv = StringVar()

              def validate_float(var):
              new_value = var.get()
              try:
              new_value == '' or float(new_value)
              validate.old_value = new_value
              except:
              var.set(validate.old_value)
              validate.old_value = ''

              # trace wants a callback with nearly useless parameters, fixing with lambda.
              sv.trace('w', lambda nm, idx, mode, var=sv: validate_float(var))
              ent = Entry(root, textvariable=sv)
              ent.pack()

              root.mainloop()





              share|improve this answer
























              • Thanks for your post. I enjoyed seeing the Tkinter StringVar .trace() method in use.

                – Malcolm
                Nov 10 '10 at 13:38














              7












              7








              7







              Use a Tkinter.StringVar to track the value of the Entry widget. You can validate the value of the StringVar by setting a trace on it.



              Here's a short working program that accepts only valid floats in the Entry widget.



              from Tkinter import *
              root = Tk()
              sv = StringVar()

              def validate_float(var):
              new_value = var.get()
              try:
              new_value == '' or float(new_value)
              validate.old_value = new_value
              except:
              var.set(validate.old_value)
              validate.old_value = ''

              # trace wants a callback with nearly useless parameters, fixing with lambda.
              sv.trace('w', lambda nm, idx, mode, var=sv: validate_float(var))
              ent = Entry(root, textvariable=sv)
              ent.pack()

              root.mainloop()





              share|improve this answer













              Use a Tkinter.StringVar to track the value of the Entry widget. You can validate the value of the StringVar by setting a trace on it.



              Here's a short working program that accepts only valid floats in the Entry widget.



              from Tkinter import *
              root = Tk()
              sv = StringVar()

              def validate_float(var):
              new_value = var.get()
              try:
              new_value == '' or float(new_value)
              validate.old_value = new_value
              except:
              var.set(validate.old_value)
              validate.old_value = ''

              # trace wants a callback with nearly useless parameters, fixing with lambda.
              sv.trace('w', lambda nm, idx, mode, var=sv: validate_float(var))
              ent = Entry(root, textvariable=sv)
              ent.pack()

              root.mainloop()






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Nov 10 '10 at 2:47









              Steven RumbalskiSteven Rumbalski

              33.3k65893




              33.3k65893













              • Thanks for your post. I enjoyed seeing the Tkinter StringVar .trace() method in use.

                – Malcolm
                Nov 10 '10 at 13:38



















              • Thanks for your post. I enjoyed seeing the Tkinter StringVar .trace() method in use.

                – Malcolm
                Nov 10 '10 at 13:38

















              Thanks for your post. I enjoyed seeing the Tkinter StringVar .trace() method in use.

              – Malcolm
              Nov 10 '10 at 13:38





              Thanks for your post. I enjoyed seeing the Tkinter StringVar .trace() method in use.

              – Malcolm
              Nov 10 '10 at 13:38











              6














              After studying and experimenting with Bryan's code, I produced a minimal version of input validation. The following code will put up an Entry box and only accept numeric digits.



              from tkinter import *

              root = Tk()

              def testVal(inStr,acttyp):
              if acttyp == '1': #insert
              if not inStr.isdigit():
              return False
              return True

              entry = Entry(root, validate="key")
              entry['validatecommand'] = (entry.register(testVal),'%P','%d')
              entry.pack()

              root.mainloop()


              Perhaps I should add that I am still learning Python and I will gladly accept any and all comments/suggestions.






              share|improve this answer


























              • Generally people use entry.configure(validatecommand=...) and write test_val instead of testVal, but this is a good, simple example.

                – wizzwizz4
                Aug 12 '18 at 14:58
















              6














              After studying and experimenting with Bryan's code, I produced a minimal version of input validation. The following code will put up an Entry box and only accept numeric digits.



              from tkinter import *

              root = Tk()

              def testVal(inStr,acttyp):
              if acttyp == '1': #insert
              if not inStr.isdigit():
              return False
              return True

              entry = Entry(root, validate="key")
              entry['validatecommand'] = (entry.register(testVal),'%P','%d')
              entry.pack()

              root.mainloop()


              Perhaps I should add that I am still learning Python and I will gladly accept any and all comments/suggestions.






              share|improve this answer


























              • Generally people use entry.configure(validatecommand=...) and write test_val instead of testVal, but this is a good, simple example.

                – wizzwizz4
                Aug 12 '18 at 14:58














              6












              6








              6







              After studying and experimenting with Bryan's code, I produced a minimal version of input validation. The following code will put up an Entry box and only accept numeric digits.



              from tkinter import *

              root = Tk()

              def testVal(inStr,acttyp):
              if acttyp == '1': #insert
              if not inStr.isdigit():
              return False
              return True

              entry = Entry(root, validate="key")
              entry['validatecommand'] = (entry.register(testVal),'%P','%d')
              entry.pack()

              root.mainloop()


              Perhaps I should add that I am still learning Python and I will gladly accept any and all comments/suggestions.






              share|improve this answer















              After studying and experimenting with Bryan's code, I produced a minimal version of input validation. The following code will put up an Entry box and only accept numeric digits.



              from tkinter import *

              root = Tk()

              def testVal(inStr,acttyp):
              if acttyp == '1': #insert
              if not inStr.isdigit():
              return False
              return True

              entry = Entry(root, validate="key")
              entry['validatecommand'] = (entry.register(testVal),'%P','%d')
              entry.pack()

              root.mainloop()


              Perhaps I should add that I am still learning Python and I will gladly accept any and all comments/suggestions.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jun 29 '18 at 0:56









              JCKE

              78110




              78110










              answered Feb 22 '16 at 13:16









              user1683793user1683793

              667613




              667613













              • Generally people use entry.configure(validatecommand=...) and write test_val instead of testVal, but this is a good, simple example.

                – wizzwizz4
                Aug 12 '18 at 14:58



















              • Generally people use entry.configure(validatecommand=...) and write test_val instead of testVal, but this is a good, simple example.

                – wizzwizz4
                Aug 12 '18 at 14:58

















              Generally people use entry.configure(validatecommand=...) and write test_val instead of testVal, but this is a good, simple example.

              – wizzwizz4
              Aug 12 '18 at 14:58





              Generally people use entry.configure(validatecommand=...) and write test_val instead of testVal, but this is a good, simple example.

              – wizzwizz4
              Aug 12 '18 at 14:58











              2














              While studying Bryan Oakley's answer, something told me that a far more general solution could be developed. The following example introduces a mode enumeration, a type dictionary, and a setup function for validation purposes. See line 48 for example usage and a demonstration of its simplicity.



              #! /usr/bin/env python3
              # https://stackoverflow.com/questions/4140437
              import enum
              import inspect
              import tkinter
              from tkinter.constants import *


              Mode = enum.Enum('Mode', 'none key focus focusin focusout all')
              CAST = dict(d=int, i=int, P=str, s=str, S=str,
              v=Mode.__getitem__, V=Mode.__getitem__, W=str)


              def on_validate(widget, mode, validator):
              # http://www.tcl.tk/man/tcl/TkCmd/ttk_entry.htm#M39
              if mode not in Mode:
              raise ValueError('mode not recognized')
              parameters = inspect.signature(validator).parameters
              if not set(parameters).issubset(CAST):
              raise ValueError('validator arguments not recognized')
              casts = tuple(map(CAST.__getitem__, parameters))
              widget.configure(validate=mode.name, validatecommand=[widget.register(
              lambda *args: bool(validator(*(cast(arg) for cast, arg in zip(
              casts, args)))))]+['%' + parameter for parameter in parameters])


              class Example(tkinter.Frame):

              @classmethod
              def main(cls):
              tkinter.NoDefaultRoot()
              root = tkinter.Tk()
              root.title('Validation Example')
              cls(root).grid(sticky=NSEW)
              root.grid_rowconfigure(0, weight=1)
              root.grid_columnconfigure(0, weight=1)
              root.mainloop()

              def __init__(self, master, **kw):
              super().__init__(master, **kw)
              self.entry = tkinter.Entry(self)
              self.text = tkinter.Text(self, height=15, width=50,
              wrap=WORD, state=DISABLED)
              self.entry.grid(row=0, column=0, sticky=NSEW)
              self.text.grid(row=1, column=0, sticky=NSEW)
              self.grid_rowconfigure(1, weight=1)
              self.grid_columnconfigure(0, weight=1)
              on_validate(self.entry, Mode.key, self.validator)

              def validator(self, d, i, P, s, S, v, V, W):
              self.text['state'] = NORMAL
              self.text.delete(1.0, END)
              self.text.insert(END, 'd = {!r}ni = {!r}nP = {!r}ns = {!r}n'
              'S = {!r}nv = {!r}nV = {!r}nW = {!r}'
              .format(d, i, P, s, S, v, V, W))
              self.text['state'] = DISABLED
              return not S.isupper()


              if __name__ == '__main__':
              Example.main()





              share|improve this answer






























                2














                While studying Bryan Oakley's answer, something told me that a far more general solution could be developed. The following example introduces a mode enumeration, a type dictionary, and a setup function for validation purposes. See line 48 for example usage and a demonstration of its simplicity.



                #! /usr/bin/env python3
                # https://stackoverflow.com/questions/4140437
                import enum
                import inspect
                import tkinter
                from tkinter.constants import *


                Mode = enum.Enum('Mode', 'none key focus focusin focusout all')
                CAST = dict(d=int, i=int, P=str, s=str, S=str,
                v=Mode.__getitem__, V=Mode.__getitem__, W=str)


                def on_validate(widget, mode, validator):
                # http://www.tcl.tk/man/tcl/TkCmd/ttk_entry.htm#M39
                if mode not in Mode:
                raise ValueError('mode not recognized')
                parameters = inspect.signature(validator).parameters
                if not set(parameters).issubset(CAST):
                raise ValueError('validator arguments not recognized')
                casts = tuple(map(CAST.__getitem__, parameters))
                widget.configure(validate=mode.name, validatecommand=[widget.register(
                lambda *args: bool(validator(*(cast(arg) for cast, arg in zip(
                casts, args)))))]+['%' + parameter for parameter in parameters])


                class Example(tkinter.Frame):

                @classmethod
                def main(cls):
                tkinter.NoDefaultRoot()
                root = tkinter.Tk()
                root.title('Validation Example')
                cls(root).grid(sticky=NSEW)
                root.grid_rowconfigure(0, weight=1)
                root.grid_columnconfigure(0, weight=1)
                root.mainloop()

                def __init__(self, master, **kw):
                super().__init__(master, **kw)
                self.entry = tkinter.Entry(self)
                self.text = tkinter.Text(self, height=15, width=50,
                wrap=WORD, state=DISABLED)
                self.entry.grid(row=0, column=0, sticky=NSEW)
                self.text.grid(row=1, column=0, sticky=NSEW)
                self.grid_rowconfigure(1, weight=1)
                self.grid_columnconfigure(0, weight=1)
                on_validate(self.entry, Mode.key, self.validator)

                def validator(self, d, i, P, s, S, v, V, W):
                self.text['state'] = NORMAL
                self.text.delete(1.0, END)
                self.text.insert(END, 'd = {!r}ni = {!r}nP = {!r}ns = {!r}n'
                'S = {!r}nv = {!r}nV = {!r}nW = {!r}'
                .format(d, i, P, s, S, v, V, W))
                self.text['state'] = DISABLED
                return not S.isupper()


                if __name__ == '__main__':
                Example.main()





                share|improve this answer




























                  2












                  2








                  2







                  While studying Bryan Oakley's answer, something told me that a far more general solution could be developed. The following example introduces a mode enumeration, a type dictionary, and a setup function for validation purposes. See line 48 for example usage and a demonstration of its simplicity.



                  #! /usr/bin/env python3
                  # https://stackoverflow.com/questions/4140437
                  import enum
                  import inspect
                  import tkinter
                  from tkinter.constants import *


                  Mode = enum.Enum('Mode', 'none key focus focusin focusout all')
                  CAST = dict(d=int, i=int, P=str, s=str, S=str,
                  v=Mode.__getitem__, V=Mode.__getitem__, W=str)


                  def on_validate(widget, mode, validator):
                  # http://www.tcl.tk/man/tcl/TkCmd/ttk_entry.htm#M39
                  if mode not in Mode:
                  raise ValueError('mode not recognized')
                  parameters = inspect.signature(validator).parameters
                  if not set(parameters).issubset(CAST):
                  raise ValueError('validator arguments not recognized')
                  casts = tuple(map(CAST.__getitem__, parameters))
                  widget.configure(validate=mode.name, validatecommand=[widget.register(
                  lambda *args: bool(validator(*(cast(arg) for cast, arg in zip(
                  casts, args)))))]+['%' + parameter for parameter in parameters])


                  class Example(tkinter.Frame):

                  @classmethod
                  def main(cls):
                  tkinter.NoDefaultRoot()
                  root = tkinter.Tk()
                  root.title('Validation Example')
                  cls(root).grid(sticky=NSEW)
                  root.grid_rowconfigure(0, weight=1)
                  root.grid_columnconfigure(0, weight=1)
                  root.mainloop()

                  def __init__(self, master, **kw):
                  super().__init__(master, **kw)
                  self.entry = tkinter.Entry(self)
                  self.text = tkinter.Text(self, height=15, width=50,
                  wrap=WORD, state=DISABLED)
                  self.entry.grid(row=0, column=0, sticky=NSEW)
                  self.text.grid(row=1, column=0, sticky=NSEW)
                  self.grid_rowconfigure(1, weight=1)
                  self.grid_columnconfigure(0, weight=1)
                  on_validate(self.entry, Mode.key, self.validator)

                  def validator(self, d, i, P, s, S, v, V, W):
                  self.text['state'] = NORMAL
                  self.text.delete(1.0, END)
                  self.text.insert(END, 'd = {!r}ni = {!r}nP = {!r}ns = {!r}n'
                  'S = {!r}nv = {!r}nV = {!r}nW = {!r}'
                  .format(d, i, P, s, S, v, V, W))
                  self.text['state'] = DISABLED
                  return not S.isupper()


                  if __name__ == '__main__':
                  Example.main()





                  share|improve this answer















                  While studying Bryan Oakley's answer, something told me that a far more general solution could be developed. The following example introduces a mode enumeration, a type dictionary, and a setup function for validation purposes. See line 48 for example usage and a demonstration of its simplicity.



                  #! /usr/bin/env python3
                  # https://stackoverflow.com/questions/4140437
                  import enum
                  import inspect
                  import tkinter
                  from tkinter.constants import *


                  Mode = enum.Enum('Mode', 'none key focus focusin focusout all')
                  CAST = dict(d=int, i=int, P=str, s=str, S=str,
                  v=Mode.__getitem__, V=Mode.__getitem__, W=str)


                  def on_validate(widget, mode, validator):
                  # http://www.tcl.tk/man/tcl/TkCmd/ttk_entry.htm#M39
                  if mode not in Mode:
                  raise ValueError('mode not recognized')
                  parameters = inspect.signature(validator).parameters
                  if not set(parameters).issubset(CAST):
                  raise ValueError('validator arguments not recognized')
                  casts = tuple(map(CAST.__getitem__, parameters))
                  widget.configure(validate=mode.name, validatecommand=[widget.register(
                  lambda *args: bool(validator(*(cast(arg) for cast, arg in zip(
                  casts, args)))))]+['%' + parameter for parameter in parameters])


                  class Example(tkinter.Frame):

                  @classmethod
                  def main(cls):
                  tkinter.NoDefaultRoot()
                  root = tkinter.Tk()
                  root.title('Validation Example')
                  cls(root).grid(sticky=NSEW)
                  root.grid_rowconfigure(0, weight=1)
                  root.grid_columnconfigure(0, weight=1)
                  root.mainloop()

                  def __init__(self, master, **kw):
                  super().__init__(master, **kw)
                  self.entry = tkinter.Entry(self)
                  self.text = tkinter.Text(self, height=15, width=50,
                  wrap=WORD, state=DISABLED)
                  self.entry.grid(row=0, column=0, sticky=NSEW)
                  self.text.grid(row=1, column=0, sticky=NSEW)
                  self.grid_rowconfigure(1, weight=1)
                  self.grid_columnconfigure(0, weight=1)
                  on_validate(self.entry, Mode.key, self.validator)

                  def validator(self, d, i, P, s, S, v, V, W):
                  self.text['state'] = NORMAL
                  self.text.delete(1.0, END)
                  self.text.insert(END, 'd = {!r}ni = {!r}nP = {!r}ns = {!r}n'
                  'S = {!r}nv = {!r}nV = {!r}nW = {!r}'
                  .format(d, i, P, s, S, v, V, W))
                  self.text['state'] = DISABLED
                  return not S.isupper()


                  if __name__ == '__main__':
                  Example.main()






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited May 23 '17 at 12:02









                  Community

                  11




                  11










                  answered May 11 '16 at 20:06









                  Noctis SkytowerNoctis Skytower

                  13.6k115888




                  13.6k115888























                      1














                      Bryan's answer is correct, however no one mentioned the 'invalidcommand' attribute of the tkinter widget.



                      A good explanation is here:
                      http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/entry-validation.html



                      Text copy/pasted in case of broken link



                      The Entry widget also supports an invalidcommand option that specifies a callback function that is called whenever the validatecommand returns False. This command may modify the text in the widget by using the .set() method on the widget's associated textvariable. Setting up this option works the same as setting up the validatecommand. You must use the .register() method to wrap your Python function; this method returns the name of the wrapped function as a string. Then you will pass as the value of the invalidcommand option either that string, or as the first element of a tuple containing substitution codes.



                      Note:
                      There is only one thing that I cannot figure out how to do: If you add validation to an entry, and the user selects a portion of the text and types a new value, there is no way to capture the original value and reset the entry. Here's an example




                      1. Entry is designed to only accept integers by implementing 'validatecommand'

                      2. User enters 1234567

                      3. User selects '345' and presses 'j'. This is registered as two actions: deletion of '345', and insertion of 'j'. Tkinter ignores the deletion and acts only on the insertion of 'j'. 'validatecommand' returns False, and the values passed to the 'invalidcommand' function are as follows: %d=1, %i=2, %P=12j67, %s=1267, %S=j

                      4. If the code does not implement an 'invalidcommand' function, the 'validatecommand' function will reject the 'j' and the result will be 1267. If the code does implement an 'invalidcommand' function, there is no way to recover the original 1234567.






                      share|improve this answer






























                        1














                        Bryan's answer is correct, however no one mentioned the 'invalidcommand' attribute of the tkinter widget.



                        A good explanation is here:
                        http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/entry-validation.html



                        Text copy/pasted in case of broken link



                        The Entry widget also supports an invalidcommand option that specifies a callback function that is called whenever the validatecommand returns False. This command may modify the text in the widget by using the .set() method on the widget's associated textvariable. Setting up this option works the same as setting up the validatecommand. You must use the .register() method to wrap your Python function; this method returns the name of the wrapped function as a string. Then you will pass as the value of the invalidcommand option either that string, or as the first element of a tuple containing substitution codes.



                        Note:
                        There is only one thing that I cannot figure out how to do: If you add validation to an entry, and the user selects a portion of the text and types a new value, there is no way to capture the original value and reset the entry. Here's an example




                        1. Entry is designed to only accept integers by implementing 'validatecommand'

                        2. User enters 1234567

                        3. User selects '345' and presses 'j'. This is registered as two actions: deletion of '345', and insertion of 'j'. Tkinter ignores the deletion and acts only on the insertion of 'j'. 'validatecommand' returns False, and the values passed to the 'invalidcommand' function are as follows: %d=1, %i=2, %P=12j67, %s=1267, %S=j

                        4. If the code does not implement an 'invalidcommand' function, the 'validatecommand' function will reject the 'j' and the result will be 1267. If the code does implement an 'invalidcommand' function, there is no way to recover the original 1234567.






                        share|improve this answer




























                          1












                          1








                          1







                          Bryan's answer is correct, however no one mentioned the 'invalidcommand' attribute of the tkinter widget.



                          A good explanation is here:
                          http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/entry-validation.html



                          Text copy/pasted in case of broken link



                          The Entry widget also supports an invalidcommand option that specifies a callback function that is called whenever the validatecommand returns False. This command may modify the text in the widget by using the .set() method on the widget's associated textvariable. Setting up this option works the same as setting up the validatecommand. You must use the .register() method to wrap your Python function; this method returns the name of the wrapped function as a string. Then you will pass as the value of the invalidcommand option either that string, or as the first element of a tuple containing substitution codes.



                          Note:
                          There is only one thing that I cannot figure out how to do: If you add validation to an entry, and the user selects a portion of the text and types a new value, there is no way to capture the original value and reset the entry. Here's an example




                          1. Entry is designed to only accept integers by implementing 'validatecommand'

                          2. User enters 1234567

                          3. User selects '345' and presses 'j'. This is registered as two actions: deletion of '345', and insertion of 'j'. Tkinter ignores the deletion and acts only on the insertion of 'j'. 'validatecommand' returns False, and the values passed to the 'invalidcommand' function are as follows: %d=1, %i=2, %P=12j67, %s=1267, %S=j

                          4. If the code does not implement an 'invalidcommand' function, the 'validatecommand' function will reject the 'j' and the result will be 1267. If the code does implement an 'invalidcommand' function, there is no way to recover the original 1234567.






                          share|improve this answer















                          Bryan's answer is correct, however no one mentioned the 'invalidcommand' attribute of the tkinter widget.



                          A good explanation is here:
                          http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/entry-validation.html



                          Text copy/pasted in case of broken link



                          The Entry widget also supports an invalidcommand option that specifies a callback function that is called whenever the validatecommand returns False. This command may modify the text in the widget by using the .set() method on the widget's associated textvariable. Setting up this option works the same as setting up the validatecommand. You must use the .register() method to wrap your Python function; this method returns the name of the wrapped function as a string. Then you will pass as the value of the invalidcommand option either that string, or as the first element of a tuple containing substitution codes.



                          Note:
                          There is only one thing that I cannot figure out how to do: If you add validation to an entry, and the user selects a portion of the text and types a new value, there is no way to capture the original value and reset the entry. Here's an example




                          1. Entry is designed to only accept integers by implementing 'validatecommand'

                          2. User enters 1234567

                          3. User selects '345' and presses 'j'. This is registered as two actions: deletion of '345', and insertion of 'j'. Tkinter ignores the deletion and acts only on the insertion of 'j'. 'validatecommand' returns False, and the values passed to the 'invalidcommand' function are as follows: %d=1, %i=2, %P=12j67, %s=1267, %S=j

                          4. If the code does not implement an 'invalidcommand' function, the 'validatecommand' function will reject the 'j' and the result will be 1267. If the code does implement an 'invalidcommand' function, there is no way to recover the original 1234567.







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Nov 20 '18 at 22:57









                          K.Dᴀᴠɪs

                          7,104112339




                          7,104112339










                          answered Nov 20 '18 at 22:39









                          orionrobertorionrobert

                          112




                          112






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f4140437%2finteractively-validating-entry-widget-content-in-tkinter%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

                              Alcedinidae

                              RAC Tourist Trophy