2

Consider this code:

from tkinter import *
from tkinter.ttk import *

tk=Tk()

def sub():
    var=StringVar(value='default value')

    def f(): pass

    Entry(tk,textvariable=var).pack()
    Button(tk,text='OK',command=f).pack()

sub()
mainloop()

We expect the value of var appears in the entry, but actually it doesn't.

nothing in the entry

The weird thing is that if I put the statement var.get() in the callback function of the button, the value of var will apear.

the value appeared

Is that a bug caused by some kind of local variable optimization in Python? And what can I do to make sure that the value of textvariable will always appear in the entry?

Please execuse me for my poor English.

martineau
  • 119,623
  • 25
  • 170
  • 301
xmcp
  • 3,347
  • 2
  • 23
  • 36
  • There's a solution to this problem, but you might want to consider _not_ using a `StringVar`; they are rarely needed. You can get and set the value via methods on the widget itself. – Bryan Oakley May 20 '16 at 16:17

1 Answers1

3

It's getting garbage collected.

You can just get rid of the function (you also shouldn't nest functions like this)

from tkinter import *
from tkinter.ttk import *

tk=Tk()

var=StringVar(value="default value")
Entry(tk, textvariable=var).pack()
Button(tk,text='OK').pack()

mainloop()

Or, if you want to keep the function.. set the stringvar as an attribute of tk or make it global.

Making it global:

from tkinter import *
from tkinter.ttk import *

tk=Tk()
var = StringVar(value="Default value")

def sub():

    Entry(tk, textvariable=var).pack()
    Button(tk,text='OK').pack()

sub()
mainloop()

As an attribute of tk:

from tkinter import *
from tkinter.ttk import *

tk=Tk()

def sub():

    tk.var = StringVar(value="Default value")
    Entry(tk, textvariable=tk.var).pack()
    Button(tk,text='OK').pack()

sub()
mainloop()
Pythonista
  • 11,377
  • 2
  • 31
  • 50