2

I am trying create small tkinter python program. It should accept only digit and underscore.

Example:

78_90_01  == Accept

89a_90_b == Through error
a90_ == Through error
_90a == Through error
_a == Through error
_a9 == Through error
89-0a == through error

If we erase and entered value and type above combination also should validate.

I tried the below program.it's not working as expetced.

import tkinter as tk
from tkinter import ttk
from tkinter import *
from tkinter.messagebox import showinfo
from tkinter import messagebox
from tkinter import filedialog
from tkinter.filedialog import askopenfile
import os
import re
import subprocess
from datetime import datetime




root = tk.Tk()
root.geometry("500x350")
root.resizable(False, False)
root.title('Test')

Generator = tk.Frame(root)
Generator.pack(padx=10, pady=10, fill='x', expand=True)
Version=tk.StringVar()
def VersionValidation(S):
    #^[0-9]+_[0-9]+$
    for letter in S:
        if re.match("^[0-9]+_[0-9]+$",letter):
           return True
        else:
            messagebox.showerror('Version','only letter and underscore allowed')
version_label = ttk.Label(Generator, text="Version",font=('Helvetica', 10, 'bold'))
version_label.pack(fill='x', expand=True)
vcmd = (Generator.register(VersionValidation), '%S')
version_entry = ttk.Entry(Generator, textvariable=Version,validate='key', validatecommand=vcmd)
version_entry.pack(fill='x', expand=True)
version_entry.focus()
Generator.mainloop()
thangaraj1980
  • 141
  • 2
  • 11

2 Answers2

1

Since you have validate='key' then

Validate whenever any keystroke changes the widget's contents.

here

Therefore, you need to check only one character for a match, and on error, the function should return False.

def VersionValidation(S):

    if re.match("[0-9_]",S):
        return True
    else:
        messagebox.showerror('Version','only letter and underscore allowed')
        return False

Сергей Кох
  • 1,417
  • 12
  • 6
  • 13
0

The regular expression in the VersionValidation in the question matches at least 3 characters, at least one digit, an underscore then at least one digit. It is matched to each character in S and one character will never match 3 characters. I think the regex below does what you want.

import tkinter as tk
from tkinter import ttk
import re

def VersionValidation(p):
    if len(p) == 0:
        return True     # Allow an empty Entry
    if re.match(r'^([0-9]+_?)+$', p ):
        return True     
    else:
        return False

root = tk.Tk()
vcmd = (root.register(VersionValidation), '%P')
# Pass the entire Entry string.  Avoids issues around delete.

tk.Entry( root, validatecommand = vcmd, validate = 'key' ).grid()

root.mainloop()

Corrected to pass the whole string.

Tls Chris
  • 3,564
  • 1
  • 9
  • 24