Reputation: 1380
The following code packs two tkinter Entry fields into the root tk window. The displayed text is set via a StringVar
. The functions that create the two fields are identical except that one creates a tkinter.Entry
object and the other creates a tkinter.ttk.Entry
object.
According to Shipman's text both the tkinter.Entry
and tkinter.ttk.Entry
have textvariable
options. They both refer to the same .get()
and .set()
method for the StringVar
. I have been unable to find anything which suggests that the ttk.Entry
class requires separate treatment.
Why does ttk.Entry
fail to show the text?
(Python 3.5.1 on MS Windows 7)
import tkinter
import tkinter.ttk
def label_2(root):
label = tkinter.ttk.Entry(root)
var_text = tkinter.StringVar(name='StringVar 2')
label.config(textvariable=var_text)
var_text.set('variable label 2')
root.update_idletasks() # Shipman recommended precaution has no effect here
print(var_text, var_text.get(), label.get())
label.pack()
def label_3(root):
label = tkinter.Entry(root)
var_text = tkinter.StringVar(name='StringVar 3')
label.config(textvariable=var_text)
var_text.set('variable label 3')
root.update_idletasks() # Shipman recommended precaution has no effect here
print(var_text, var_text.get(), label.get())
label.pack()
if __name__ == '__main__':
root = tkinter.Tk()
label_2(root)
label_3(root)
root.mainloop()
Upvotes: 2
Views: 2513
Reputation: 146
I use var_text.trace_add('write', lambda val, index, value: var_text.get())
to keep the reference. Between clases works for me.
Upvotes: 0
Reputation: 386020
Due to differences in implementation, the ttk version of the widget is susceptible to having the variable be garbage-collected. If you keep a persistent reference to the variable your code will work. For example, if you add global var_text
inside label_2
, it will work.
Personally I see no value in using a StringVar
with Entry
widgets, unless you are relying on some of the special features of the class such as variable traces, or connecting more than one widget to the same variable.
Note: calling update_idletasks
in these functions is completely pointless. This is doubly true since you're calling it before calling pack
. That is, until you call pack
or grid
or place
, no task will be added to the idle queue for this particular widget. update_idletask
will only affect widgets that have been added to the screen but not drawn yet.
And while you think it has no side effect, it actually does. Calling update_idletasks
refreshes all idle tasks, not just the ones created in this function. That being said, it's harmless because all it does is cause a screen refresh, which will happen anyway as soon as mainloop is called.
Upvotes: 3