[Tkinter-discuss] how do I pass variables when binding to a widget?

Michael Lange klappnase at web.de
Thu Jan 10 05:02:38 EST 2019


Hi Chris,

On Thu, 10 Jan 2019 15:13:12 +1100
Chris Roy-Smith <chris_roysmith at internode.on.net> wrote:

> Hi
> System: 	Linux,
> Python Version:	3.6.7
> 
> I am trying to learn how to bind to a widget, and process the contents 
> of the bound widget
(...)
> I get the following traceback:
> 
> Traceback (most recent call last):
>    File "./bind.py", line 19, in <module>
>      first.bind("<Return>", NewAge(first.get()))
>    File "./bind.py", line 7, in NewAge
>      futureAge = start + 5
> TypeError: must be str, not int

here for some reason the traceback looks slightly different:

~$ python3 test4.py

Traceback (most recent call last):
  File "test4.py", line 24, in <module>
    first.bind("<Return>", NewAge(first.get()))
  File "test4.py", line 19, in NewAge
    futureAge = start + 5
TypeError: Can't convert 'int' object to str implicitly

What happens becomes a bit more obvious if you change your code a bit
like this:

  (...)
  first=Entry(master)
  first.grid(row=0, column=1)
  # add a default value in the first entry
  first.insert('end', 25)
  calculated = Entry(master)
  calculated.grid(row=1, column=1)
  first.bind("<Return>", NewAge(first.get()))
  (...)

Then the traceback here looks like:

~$ python3 test4.py
25
Traceback (most recent call last):
  File "test4.py", line 21, in <module>
    first.bind("<Return>", NewAge(first.get()))
  File "test4.py", line 8, in NewAge
    futureAge = start + 5
TypeError: Can't convert 'int' object to str implicitly

So, what happens is, that as soon as your bind() function call is
processed the NewAge() function is called with first.get() as argument.
Since first.get() will always return a string, trying to add an integer
value will of course cause an error.

To fix this you need to change the call to bind(), so that the second
argument is the function NewAge itself, not a *call* to that function, as
in:

  first.bind("<Return>", NewAge)

After the binding has been applied, each time the <Return> event occurs
on that widget, the NewAge function will be called by tkinter with an
Event object as argument. So the definition of the NewAge function might
for example look like this:

def NewAge(event):
    try:
        futureAge = int(event.widget.get()) + 5
        calculated.delete(0,END)
        calculated.insert(0,futureAge)
    except ValueError:
        event.widget.bell()

If you want to learn more about Events (and tkinter in general), John
Shipman's excellent tkinter reference is an invaluable source of
knowledge:

https://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html
About tkinter Events:
https://infohost.nmt.edu/tcc/help/pubs/tkinter/web/events.html

And of course you are always welcome here to ask further questions.

I hope this helps.

Michael


.-.. .. ...- .   .-.. --- -. --.   .- -. -..   .--. .-. --- ... .--. . .-.

... bacteriological warfare ... hard to believe we were once foolish
enough to play around with that.
		-- McCoy, "The Omega Glory", stardate unknown


More information about the Tkinter-discuss mailing list