3

I am trying to activate callback function as the user type in to the tkinter entry box. According to effbot.org,

You can use the trace method to attach “observer” callbacks to the variable. The callback is called whenever the contents change:

So i tired this,

import Tkinter as tk
window2=tk.Tk()
anf_frame1=tk.Frame(window2,bg='white',relief='groove',bd=0,width=1190,height=175)
anf_frame1.place(x=10,y=50)

def myfunction(*args):
        print 'pass'
stringvar1 = tk.StringVar(anf_frame1)
stringvar1.trace("w", myfunction)
anf_fault_entry=tk.Entry(anf_frame1,width=35,font=('calibri',(14)),bg='white',textvariable=stringvar1)
anf_fault_entry.grid(row=2,column=1,padx=(5,5))

window2.mainloop()

The above script works fine.But when i copy this to my main script, it doesn't print out the 'pass' anymore. It doesn't give me any error either.

I have confirmed that there is no other variable name stringvar1 and same function name myfunction. And there is no typo error as i just used copy paste function.

I am now puzzled why it doesn't work when i copy it to my main script.

Just for info, my main script is working as it should before i copy the trace callback and after. My main script has tkinter window with a few labels and entry boxes which should not affect the above operation. What is causing the problem? Did i miss something?

--- EDIT ---

def Entrybox_002():
    def myfunction(*args):
            print 'pass'

    window2=tk.Toplevel(root)
    md1.Drag_Window(window2, nf_sizex, nf_sizey, nf_posx, nf_posy, nf_title, nf_titlesize,nf_level)    
    ''' New Entry labels & Dropdowns'''
    #Frame to hold labels
    anf_frame1=tk.Frame(window2,bg='white',relief='groove',bd=0,width=1190,height=175)
    anf_frame1.place(x=10,y=50)
    anf_frame2=tk.Frame(window2,bg='#CCF1FF',relief='groove',bd=0,width=700,height=85)
    anf_frame2.place(x=50,y=140)

    label_list=['JCN','Fault','System','Sub-System','Status','Faultcode']
    for i in range (6):
        tk.Label(anf_frame1,text=label_list[i],font=('calibri',(16)),bg='white').grid(row=1,column=i,padx=(40,40),pady=(5,5))

    anf_jcn_number=tk.Label(anf_frame1,text=Calculate_linenumber(),font=('calibri',(16)),bg='white',fg='blue')
    anf_jcn_number.grid(row=2,column=0)


    stringvar1 = tk.StringVar(anf_frame1)    
    stringvar1.trace("w", myfunction)
    anf_fault_entry=tk.Entry(anf_frame1,width=35,font=('calibri',(14)),bg='white',textvariable=stringvar1) #<------------------------ENTRY BOX THAT I AM TRYING TO TRACE
    anf_fault_entry.grid(row=2,column=1,padx=(5,5))

    anf_system_menu = md1.MyOptionMenu(anf_frame1, 'Select System', anf_system_choices,Subsytem_display)
    anf_system_menu.grid(row=2,column=2,padx=(5,5))
    (anf_system_menu.var).trace("w",myfunction)

    anf_status_menu = md1.MyOptionMenu(anf_frame1, 'Select Status', anf_status_choices,Subsytem_display)
    anf_status_menu.grid(row=2,column=4,padx=(5,5))
    (anf_status_menu.var).trace("w",myfunction) 


    anf_faultcode_menu1 = md1.MyOptionMenu(anf_frame1, 'When fault found?', anf_faultcode_1,Operational_effect)
    anf_faultcode_menu1.grid(row=2,column=5,padx=(5,5))  
    (anf_faultcode_menu1.var).trace("w",myfunction) 

    anf_date_button=tk.Button(anf_frame2,image=images.adf_date_chooser,text='Date',compound='left',font=('calibri',(12),'italic'),bg='white',command=Create_calendar)
    anf_date_button.grid(row=1,column=0,padx=(15,15),pady=(5,5))

    anf_ownership=tk.Label(anf_frame2,text='Reported by',font=('calibri',(14),'italic'),bg='#CCF1FF')
    anf_ownership.grid(row=1,column=1,padx=(15,15),pady=(5,5))

    anf_date_label=tk.Label(anf_frame2,text=today_date,font=('calibri',(14),'italic'),bg='#CCF1FF',fg='blue')
    anf_date_label.grid(row=2,column=0,padx=(15,15),pady=(5,5))

    anf_button1=tk.Button(window2,text='Submit',relief='groove',bd=1,font=('calibri',(12)),bg='green',padx=10,pady=3,command=Submit_Newfault)
    anf_button1.place(x=1100,y=175)
    anf_button1.config(state='normal',bg='grey')

This is the function that create the entry box (anf_fault_entry) i was asking about. It is on a top level window with other several widgets. I tried to trace the other option menus (for example anf_system_menu and anf_subsystem_menu) using the same function i used for entry box but it seems working fine for those option menu. I have no idea what's going on.

martineau
  • 119,623
  • 25
  • 170
  • 301
Chris Aung
  • 9,152
  • 33
  • 82
  • 127
  • Your main script had mainloop() call? and now two mainloop() calls? – falsetru Jun 16 '13 at 10:40
  • Without seeing the non-functioning code it's impossible for us to guess what you did wrong. – Bryan Oakley Jun 16 '13 at 11:44
  • @falsetru there is only 1 mainloop() call as it should. What more puzzling is that i added 1 new optionmenu and trace the "stringvar" of that optionmenu with the same funtion and it works fine as it should.. what could have possibly gone wrong? – Chris Aung Jun 16 '13 at 11:55
  • Can you post your main code somewhere? I can't guess any other cause. – falsetru Jun 16 '13 at 11:57
  • @falsetru added the potion of code that is causing the problem. – Chris Aung Jun 16 '13 at 12:28

1 Answers1

3

stringvar1 is garbage collected (deleted) when Entrybox_002 function return.

Workaround:

stringvar1 = window2.stringvar1 = tk.StringVar(value='asdf')

I recommend you code Entrybox_002 as class, and stringvar1 as instance attribute to keep reference.

falsetru
  • 357,413
  • 63
  • 732
  • 636
  • Thanks you so much. that fixed the problem..i have been spending last 2 hrs troubleshooting that problem. i am a beginner so i have no idea about the garbage collector.. i have to read up more about it. – Chris Aung Jun 16 '13 at 13:02