Louisono
Louisono

Reputation: 11

tkinter : Spinbox, validatecommand and invalidcommand

I'm trying to use a Spinbox widget in a script and I would like the Spinbox not to accept incorrect input. I would like the input to be an integer between 0 and 50. I found that I could use the option validatecommand to call a registered function to check the input, and the option invalidcommand to do stuff if the function called by validatecommand returns False. So what I want is:

Here's my code for setting the Spinbox:

import tkinter as tk

root = tk.Tk()

validate_input = (root.register(correct_input), '%P')
invalid_input = (root.register(incorrect_input), '%W')

x_select = tk.Spinbox(root, from_ = 0, to = 50,
                      validate = 'all', validatecommand = validate_input,
                      invalidcommand = invalid_input)
x_select.grid(row = 1, column = 0, columnspan = 2)

And here are the functions used to control the input and to change it back to a default value if necessary:

def correct_input(text):
    valid = False
    if text.isdigit():
        if (int(text) <= 50 and int(text) >= 0):
            valid = True
    elif text == '':
        valid = True
    return valid

def incorrect_input(widget_name):
    widget = root.nametowidget(widget_name)
    widget.delete(0, 'end')
    widget.insert(0, 0)

Problem is, it only works once: if I type 'a' for instance the value in x_select will be set to 0 but then input is not checked anymore i.e. I can type whatever I want the input will not be corrected. What am I doing wrong here?

Upvotes: 0

Views: 2214

Answers (1)

Louisono
Louisono

Reputation: 11

After checking some documentation I found out using the invalidcommand was unnecessary since

a callback function checks the text in the Entry and returns True if the text is valid, or False if not. If the callback returns False, the user's attempt to edit the text will be refused, and the text will be unchanged.

Here my callback function is correct_input: if it returns False, text will not be changed. So instead of having:

x_select = tk.Spinbox(root, from_ = 0, to = 50,
                      validate = 'all', validatecommand = validate_input,
                      invalidcommand = invalid_input)

I just write:

x_select = tk.Spinbox(root, from_ = 0, to = 50,
                      validate = 'all', validatecommand = validate_input)

And I deleted any line related to incorrect_input.

Upvotes: 1

Related Questions