VanN
VanN

Reputation: 17

How to pass string var in callback function using trace() in tkinter

I am new with python and trying to create two entry widgets to evaluate the data as soon as the user typed in the entry box. How to pass the string var into a function callback so that it will return exactly which entry box has changed. Now the callback function just returns the first entry box (entry1).

Here is my code:

import tkinter
from tkinter import StringVar

main_wd = tkinter.Tk()
my_var1 = StringVar()
my_var2 = StringVar()

def my_callback(var):
    print("Traced variables {}".format(var.get())

my_var1.trace('write', my_callback(my_var1))
my_var2.trace('write', my_callback(my_var2))
entry1 = tkinter.Entry(main_wd, textvariable = my_var1).pack(padx = 5, pady = 5)
entry2 = tkinter.Entry(main_wd, textvariable = my_var2).pack(padx = 5, pady = 5)

main_wd.mainloop() 

Upvotes: 0

Views: 1156

Answers (1)

Delrius Euphoria
Delrius Euphoria

Reputation: 15098

To being in with, the usage of trace is wrong, meaning, the positional argument passed is wrong, it has to be 'w' instead of 'write'. Then next your calling the function when you use (), so you need to use lambda for that. So you trace would be like:

my_var1.trace('w', lambda *_,var=my_var1: my_callback(*_,var=var)) #*_ are the other arguments, like varname,value,mode ?
my_var2.trace('w', lambda *_,var=my_var2: my_callback(*_,var=var))

Then your function would be like:

def my_callback(*args,var):
    print("Traced variables {}".format(var.get()))

TIP: Its better for entry1 and entry2 to not be None, so say:

entry1 = tkinter.Entry(main_wd, textvariable = my_var1)
entry1.pack(padx = 5, pady = 5)

entry2 = tkinter.Entry(main_wd, textvariable = my_var2)
entry2.pack(padx = 5, pady = 5)

When saying pack() on same line as the declaration, it will return what the last method returns. In this case, pack() returns None. So to make those entry widgets reusable, pack() them on separate line. Same applies to grid() and place().

Final Code:

import tkinter
from tkinter import StringVar

main_wd = tkinter.Tk()
my_var1 = StringVar()
my_var2 = StringVar()

def my_callback(*args,var):
    print("Traced variables {}".format(var.get()))
    
my_var1.trace('w', lambda *_,var=my_var1: my_callback(*_,var=var))
my_var2.trace('w', lambda *_,var=my_var2: my_callback(*_,var=var))

entry1 = tkinter.Entry(main_wd, textvariable = my_var1)
entry1.pack(padx = 5, pady = 5)

entry2 = tkinter.Entry(main_wd, textvariable = my_var2)
entry2.pack(padx = 5, pady = 5)

main_wd.mainloop() 

Upvotes: 4

Related Questions