In the following code snippet, I want my Tkinter program to get the values from text fields and store it in variables. But the problem is, the values stored are default StringVar()
variable values ('') and not the ones from the text field. I tried using get()
method without success.
The code:-
var_stor = [hpw_cb.cget(key='onvalue'), mil_cb.cget(key='onvalue')]
car1_hpw = StringVar()
car1_mil = StringVar()
car1_val = []
# For Car1 Window
hpw_lb_c1 = Label(c1, text="Horsepower")
hpw_ifl_c1 = Entry(c1, textvariable=car1_hpw)
mil_lb_c1 = Label(c1, text="Mileage")
mil_ifl_c1 = Entry(c1, textvariable=car1_mil)
c1_ftr_grp = [hpw_lb_c1, hpw_ifl_c1, mil_lb_c1, mil_ifl_c1]
for i in var_stor:
if i == "Horsepower":
c1_ftr_grp[0].pack(padx=12, pady=20)
c1_ftr_grp[1].pack(padx=12, pady=20)
car1_hpw_str = car1_hpw.get()
car1_val.append(car1_hpw_str)
print(car1_hpw.get())
elif i == "Mileage":
c1_ftr_grp[2].pack(padx=12, pady=20)
c1_ftr_grp[3].pack(padx=12, pady=20)
car1_mil_str = car1_mil.get()
car1_val.append(car1_mil_str)
print(car1_mil.get())
print(car1_val)
The problem variables are:- car1_hpw, car1_mil
How to rectify this problem?
CodePudding user response:
It cannot get the value instantly. You need to use a button for it. Make button call a function where you get the value and then you do stuff with it. I also see you are using entries. Entry does not need a StringVar()
to get the value. it just needs the name of an object that you stored into a variable.
CodePudding user response:
You can trigger the function from many different events. It depends what is required. Below the are 3 possible ways but its only a sample.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
focus_v = tk.StringVar()
trace_v = tk.StringVar()
wait_v = tk.StringVar()
fmt = { 'padx': 5, 'pady': 5 }
r = 0
ttk.Label( root, text = 'Act on losing focus' ).grid( row = r, column = 0, **fmt )
ent_focus = ttk.Entry( root, textvariable = focus_v )
ent_focus.grid( row = r, column = 1, **fmt )
result_f = ttk.Label( root, text = "" )
result_f.grid( row = r, column = 2, **fmt )
r = 1
ttk.Label( root, text = 'Act on StringVar Change' ).grid( row = r, column = 0, **fmt )
ent_trace = ttk.Entry( root, textvariable = trace_v )
ent_trace.grid( row = r, column = 1, **fmt )
result_t = ttk.Label( root, text = "" )
result_t.grid( row = r, column = 2, **fmt )
r = 1
l = ttk.Label( root, text = 'Act on no key entered for 1 second' )
l.grid( row = r, column = 0, **fmt )
ent_wait = ttk.Entry( root, textvariable = wait_v )
ent_wait.grid( row = r, column = 1, **fmt )
result_w = ttk.Label( root, text = "" )
result_w.grid( row = r, column = 2, **fmt )
def on_focus_out( event ):
""" Change the result label once the Entry loses the focus """
result_f.config( text = focus_v.get() )
def on_trace( a, b, c ):
""" Change the result label as the StringVar changes. """
result_t.config( text = trace_v.get() )
def on_after():
result_w.config( text = wait_v.get() )
def noop():
return None
after_v = root.after(1, noop )
def on_wait( event ):
""" Change the result label if no new key is pressed for a second. """
global after_v
root.after_cancel( after_v ) # Clear the old after call
after_v = root.after( 1000, on_after ) # Create a new one called in 1000 ms
ent_focus.bind( '<FocusOut>', on_focus_out ) # bind event and callback to entry.
trace_v.trace( 'w', on_trace ) # set the trace function to the StringVar
ent_wait.bind( '<Key>', on_wait ) # Bind the <Key> event to the entry
root.mainloop()