Home > database >  StringVar variables do not return value
StringVar variables do not return value

Time:04-05

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()
  • Related