0

I am writing a program in Python 3.6 using Tkinter where a customer has multiple(11) entry fields. I want these entry fields to only accept integers and also be able to define the maximum amount of characters.

I already have a function that does this. But this function only works for one entry field. I have tried entering variables with calling the function so it changes another entry field for example. I was not able to do this.

This is the function I have that works with 1 entry field.

    def limitMuntgeld(self, *args):
        value = self.invoerM.get()
        if len(value) > 5:
            self.invoerM.set(value[:5])
        if value.lower() in "abcdefghijklmnopqrstuvwxyz-=[];/":
            self.invoerM.set(value[:0])

This is the example entry field code that works with the function

self.invoerMuntgeld = Entry(self, font=('Arial', 14), textvariable=self.invoerM)

This is combined with a trace on the entry field posted below.

self.invoerM = StringVar()
self.invoerM.trace('w', self.limitMuntgeld)

I have also tried it with vcmd and validatecommand. However, no good results. My endresult would be one function working with all entry fields. If anyone has any suggestions, I am all ears!

martineau
  • 119,623
  • 25
  • 170
  • 301
Cris1660
  • 3
  • 1
  • 3
  • 3
    using `validatecommand` is the proper way to do this type of validation. Perhaps you can show what you tried. – Bryan Oakley Mar 02 '18 at 14:26
  • 1
    please provide a testable example. Try to follow the [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). guidelines. – Mike - SMT Mar 02 '18 at 14:49

1 Answers1

6

The proper way to do entry validation is with the validatecommand option rather than using trace. With the validation feature built into the widget you don't need a reference to the widget itself (though you can use it if you want).

When the validatecommand is run, you can have it pass in what the new value will be if the input is valid. You only need to check this value and then return True or False, without having to know which widget it applies to.

For example:

import tkinter as tk

def validate_input(new_value):
    valid = new_value .isdigit() and len(new_value) <= 5
    return valid

root = tk.Tk()

validate = root.register(validate_input)
for i in range(10):
    entry = tk.Entry(root, validate="key", validatecommand=(validate, "%P"))
    entry.pack(side="top", fill="x")

root.mainloop()

For information about what %P represents, and what else can be used as arguments to the command, see this question: Interactively validating Entry widget content in tkinter

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Thank you very much. It seems that I was using the function in a poor way and had a bad result. It is also due to the fact that I just started using classes and might not be too efficient in that way of working. – Cris1660 Mar 02 '18 at 17:09
  • Sorry to bother again, but I don't fully understand how the validatecommand works. I understand that "%P" is given with the function. How does this continue? I have a small error in my code now. The entry box only allows integers. But when I "backspace"" the integers, the first integer will not be removed. – Cris1660 Mar 02 '18 at 18:52
  • @Cris1660: It's pretty simple: if the function returns `True`, the modification is allowed. The first integer will not be removed because the code doesn't allow the empty string. Just add a case that returns `True` if the new value is blank. – Bryan Oakley Mar 02 '18 at 18:56