Praveen Gopinath
Praveen Gopinath

Reputation: 1

Tkinter event not trigerred in all child windows.

in my code, the main window is emitting event signals, which are to be caught by the child windows, which will show the change in a label. But only the last child window catches the event signal, and changes it's label. what's wrong?

from Tkinter import *
from threading import Timer as tt

class main(Tk):
    def __init__(self):
        Tk.__init__(self)
        tt(.5,self.timedsig).start()
        for  i in range (5):
            child(self,i)

    def timedsig(self):
        self.event_generate("<<timedsig>>")
        tt(.5,self.timedsig).start()


class child(Toplevel):
    def __init__(self,master,num):
        Toplevel.__init__(self)
        self.title(str(num))
        self.num=num
        self.var=IntVar()
        self.var.set(0)
        Label(self,textvariable=self.var).pack()
        self.master=master
        self.master.bind("<<timedsig>>",self.changelabel)

    def changelabel(self,e):
        print  self.num,self.var.get()
        self.var.set(self.var.get()+1)


if __name__=="__main__":
    main().mainloop()

Upvotes: 0

Views: 184

Answers (1)

Novel
Novel

Reputation: 13729

Calling bind also unbinds all previous functions. To bind an additional function, you need to use the optional 3rd argument:

self.master.bind("<<timedsig>>",self.changelabel, '+')

But that's pretty silly to do in your case when you can simply pass the variable to the instances:

import Tkinter as tk

class Main(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.var = tk.IntVar(value=0)
        for  i in range (5):
            Popup(self, i, self.var)
        self.timedsig() # start the looping

    def timedsig(self):
        self.var.set(self.var.get() + 1)
        self.after(500, self.timedsig) # call this again in 500 ms

class Popup(tk.Toplevel):
    def __init__(self, master, num, var):
        tk.Toplevel.__init__(self)
        self.title(str(num))
        lbl = tk.Label(self,textvariable=var)
        lbl.pack()

if __name__=="__main__":
    root = Main()
    root.mainloop()

Also, that's not what we usually call a "child". It's just a different object.

Upvotes: 1

Related Questions