I’m starting with python and I wanted to create a rock, paper, scissors game using tkinter.
So I created an entry to prompt the user for their name/username, and using some code I found I made so that the entry doesn’t allow to use spaces or to write a name longer than 12 characters.
I also made an advice label that tells the user when they encounter this limitations.
The problem is that I want to use this function more times, so i want to place the advise label in some other entries that are in other positions, and the best way to do so is to use arguments. But I can’t figure out how to pass them throught the validation function.
So this is some recreation code that actually works, because the arguments values were manually placed where they should be:
import tkinter as tk
root = tk.Tk()
class Main(tk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.pack(expand= True, fill='both')
self.columnconfigure((0,1), weight= 1)
self.rowconfigure((0,1,2,3),weight= 1)
# I dont understand how this works
self.vcmd= (self.register(self.validate), '%P')
# Creation and grid setup of the entry
self.entry_name= tk.Entry(self, text= '', validate= 'key', validatecommand=self.vcmd)
self.entry_name.grid(row= 3, column= 0, sticky= 'nesw')
#I don't know how can I give the entry and parent parmeters
def validate(self, P, entry= tk.Entry, parent= tk.Frame):
# I should get the grid info from the entry
info= self.entry_name.grid_info()
advise_text= tk.StringVar()
advise_label= tk.Label(self,textvariable= advise_text) #I set the error label in the parent frame
if ' ' in P:
#if there are spaces, reject it
advise_text.set('Spaces not allowed')
advise_label.grid(row= info['row'], column= info['column'], sticky= 'e') #I place the error message in the same grid position as the entry
advise_label.after(1000, lambda: advise_label.destroy())
return False
if len(P) <= 12:
# Entry with shorter than 12 characters is ok
return True
else:
# Anything else, reject it
advise_text.set(f'12 characters max')
advise_label.grid(row= info['row'], column= info['column'], sticky= 'e') #I place the error message in the same grid position as the entry
advise_label.after(1000, lambda: advise_label.destroy())
return False
root.geometry('600x600')
main=Main(root)
root.mainloop()
And this is how i want it to work but i don’t know how to pass the arguments from the validatecommand:
import tkinter as tk
root = tk.Tk()
class Main(tk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.pack(expand= True, fill='both')
self.columnconfigure((0,1), weight= 1)
self.rowconfigure((0,1,2,3),weight= 1)
# I dont understand how this works
self.vcmd= (self.register(self.validate), '%P')
# Creation and grid setup of the entry
self.entry_name= tk.Entry(self, text= '', validate= 'key', validatecommand=self.vcmd)
self.entry_name.grid(row= 3, column= 0, sticky= 'nesw')
#I don't know how can I give the entry and parent parmeters
def validate(self, P, entry= tk.Entry, parent= tk.Frame):
# I should get the grid info from the entry
info= entry.grid_info()
advise_text= tk.StringVar()
advise_label= tk.Label(parent,textvariable= advise_text) #I set the error label in the parent frame
if ' ' in P:
#if there are spaces, reject it
advise_text.set('Spaces not allowed')
advise_label.grid(row= info['row'], column= info['column'], sticky= 'e') #I place the error message in the same grid position as the entry
advise_label.after(1000, lambda: advise_label.destroy())
return False
if len(P) <= 12:
# Entry with shorter than 12 characters is ok
return True
else:
# Anything else, reject it
advise_text.set(f'12 characters max')
advise_label.grid(row= info['row'], column= info['column'], sticky= 'e') #I place the error message in the same grid position as the entry
advise_label.after(1000, lambda: advise_label.destroy())
return False
root.geometry('600x600')
main=Main(root)
root.mainloop()
I apreciate if you can help me understand how does the register and validatecommand works, and therefor solve this problem.
Pedro Villarrubia Betancort is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.