#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Location
    California, USA
    Posts
    76
    Rep Power
    2

    Can Child Window Change Label Text in Parent Window


    I am expanding on a previous post about passing arguments between
    modules. I modified the code I received from this forum.

    I have a parent window with a label and a child window with an entry box,
    and each window is created in a separate module.
    I am trying to get the entry text (child) to show up in the label of the parent window
    when the child window closes. Possible or not?
    This is the current error message when closing the child window:
    Exception in Tkinter callback
    Traceback (most recent call last):
    File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
    return self.func(*args)
    File "C:\Python33\Lib\idlelib\MyPgms\pywin2.py", line 32, in close_windows
    self.parent.var_sent.set(self.e.get())
    File "C:\Python33\lib\tkinter\__init__.py", line 1832, in __getattr__
    return getattr(self.tk, attr)
    AttributeError: 'tkapp' object has no attribute 'var_sent'

    Scripts:
    Code:
    #pywin1.py  -  opens child window from pywin2.py via button click
    from tkinter import *
    import tkinter as tk
    import pywin2
    
    class Demo1:
        def __init__(self, master):
            self.master = master
            
            self.frame = tk.Frame(self.master)
            tk.Button(self.frame, text = 'New Window',
                width = 25, font=('Helvetica', 14),
                command = self.new_window).pack()
            self.frame.pack()
    
            self.var_sent = StringVar()
    
            tk.mylabel = Label(self.master, textvariable=self.var_sent,
                font=('Helvetica', 16))
            tk.mylabel.pack(side=LEFT, anchor=SW, fill=X, expand=YES)
            
            self.var_sent.set('Welcome')
    
            tk.Button(self.frame, text = 'Exit', font=('Helvetica', 14),
                width = 25, command = master.destroy).pack()
        
        def new_window(self):
            master = self.master
            pywin2.Demo2(tk.Toplevel(master), self.var_sent)
    
    def main():
        root = tk.Tk()
        root.geometry('300x200+20+20')
        app = Demo1(root)
        root.mainloop()
    
    if __name__ == '__main__':
        main()
    Code:
    #pywin2.py  - imported by pywin1.py
    import tkinter as tk
    
    class Demo2:
        def __init__(self, master, var_sent):
            self.parent = master.nametowidget(master.winfo_parent())
            self.master = master
            self.master.geometry('300x200+20+20')
            self.master.config(bg='NavajoWhite1')
            
            self.frame = tk.Frame(self.master)
            
            self.label = tk.Label(self.frame, text = 'Type Return Message',
                font=('Helvetica', 14))
            self.label.pack(side=tk.TOP, anchor=tk.S, fill=tk.X, expand=tk.YES)
    
            self.e = tk.Entry(self.frame, width=25, font=('Helvetica', 14))
            self.e.pack()
           
            self.quitButton = tk.Button(self.frame, text = 'Close Window', width = 25,
                font=('Helvetica', 14), command = self.close_windows)
            self.quitButton.pack()
     
            self.frame.pack()
            
            self.parent.withdraw()
       
        def close_windows(self):
            self.parent.deiconify()
    
            self.parent.config(bg='cyan') 
            #self.parent.var_sent.set(self.e.get())  #this raises error
            self.master.destroy()
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Location
    California, USA
    Posts
    76
    Rep Power
    2
    Here are the scripts that produce the effect that I want: change parent window
    widget attributes from a separate module that opens a child window. Color change was
    not an issue but it was interesting to see that that can be done too.

    I don't know if this is called passing the object, but that's how I made it work.

    The idea is to be able to modulize the application, where the child windows and their
    functions are in separate modules. For certain operations with the child windows,
    such as deletions, it would be convenient to display the new count back in the parent window
    immediately after the child window is closed.

    I welcome any comments.

    scripts:
    Code:
    #pywin1.py  -  opens child window from pywin2.py via button click
    from tkinter import *
    import tkinter as tk
    import pywin2
    
    class Demo1:
        def __init__(self, master):
            self.master = master
            
            self.frame = tk.Frame(self.master)
            tk.Button(self.frame, text = 'New Window',
                width = 25, font=('Helvetica', 14),
                command = self.new_window).pack()
            self.frame.pack()
    
            self.msgLabel = Label(self.frame, width = 25,
                font=('Helvetica', 14))
            self.msgLabel.pack()
            
            tk.Button(self.frame, text = 'Exit', font=('Helvetica', 14),
                width = 25, command = master.destroy).pack()
    
        def new_window(self):
            master = self.master
            pywin2.Demo2(tk.Toplevel(master), self.msgLabel)
    
    def main():
        root = tk.Tk()
        root.geometry('300x200+20+20')
        app = Demo1(root)
        root.mainloop()
    
    if __name__ == '__main__':
        main()
    Code:
    #pywin2.py  - imported by pywin1.py
    import tkinter as tk
    
    class Demo2:
        def __init__(self, master, msgLabel):
            self.parent = master.nametowidget(master.winfo_parent())
            self.master = master
            self.master.geometry('300x200+20+20')
            self.master.config(bg='NavajoWhite1')
                    
            self.frame = tk.Frame(self.master)
            
            self.label = tk.Label(self.frame, text = 'Type a Return Message',
                font=('Helvetica', 14))
            self.label.pack(side=tk.TOP, anchor=tk.S, fill=tk.X, expand=tk.YES)
    
            self.e = tk.Entry(self.frame, width=25, font=('Helvetica', 14))
            self.e.pack()
            
            self.quitButton = tk.Button(self.frame, text = 'Close Window', width = 25,
                font=('Helvetica', 14), command = lambda: self.close_windows(msgLabel))
            self.quitButton.pack()
     
            self.frame.pack()
            
            self.parent.withdraw()
            self.e.focus_force()
           
        def close_windows(self, msgLabel):
            self.parent.deiconify()
            msgLabel.config(text=self.e.get(), bg='cyan')
            self.parent.config(bg='cyan')
            
            self.master.destroy()
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    May 2009
    Posts
    506
    Rep Power
    33
    I am trying to get the entry text (child) to show up in the label of the parent window
    when the child window closes
    All instance objects of Demo2 remain as long as the class instance remains are are available to the parent. Also, you have to have some method to check periodically if the window is open or closed.
    Code:
    ## There is probably a better way to do this than this hack
    
    try:
        import Tkinter as tk     ## Python 2.x
    except ImportError:
        import tkinter as tk     ## Python 3.x
    
    class Demo2:
        def __init__(self, demo1_master, var_sent):
            self.destroyed = False
            self.demo2_master = tk.Toplevel(demo1_master)        
    #        self.parent = master.nametowidget(master.winfo_parent())
    #        self.master = master
            self.demo2_master.geometry('300x200+20+50')
            self.demo2_master.config(bg='NavajoWhite1')
            
            self.frame = tk.Frame(self.demo2_master)
            
            self.label = tk.Label(self.frame, text = 'Type Return Message',
                font=('Helvetica', 14))
            self.label.pack(side=tk.TOP, anchor=tk.S, fill=tk.X, expand=tk.YES)
    
            self.e = tk.Entry(self.frame, width=25, font=('Helvetica', 14))
            self.e.pack()
           
            self.quitButton = tk.Button(self.frame, text = 'Close Window', width = 25,
                font=('Helvetica', 14), command = self.close_windows)
            self.quitButton.pack()
     
            self.frame.pack()
            
    ##        self.parent.withdraw()
       
        def close_windows(self):
            """
            self.demo2_master.deiconify()
            #self.demo1_master.config(bg='cyan') 
            #self.parent.var_sent.set(self.e.get())  #this raises error
            """
    
            ## self.e does not remain after the destroy()
            ## so get contents and save in a variable
            self.entry = self.e.get()
            self.destroyed = True
            self.demo2_master.destroy()
    
    class Demo1:
        def __init__(self):
            self.destroyed = False
            self.master = tk.Tk()
            self.master.geometry('300x200+20+20')
            
            self.frame = tk.Frame(self.master)
            tk.Button(self.frame, text = 'New Window',
                width = 25, font=('Helvetica', 14),
                command = self.new_window).pack()
            self.frame.pack()
    
            self.var_sent = tk.StringVar()
    
            self.mylabel = tk.Label(self.master, textvariable=self.var_sent,
                font=('Helvetica', 16))
            self.mylabel.pack(side=tk.LEFT, anchor=tk.SW, fill=tk.X, expand=tk.YES)
            
            self.var_sent.set('Welcome')
    
            tk.Button(self.frame, text = 'Exit', font=('Helvetica', 14),
                width = 25, command = self.master.quit).pack()
        
            self.master.mainloop()
    
        def new_window(self):
            demo2 = Demo2(self.master, self.var_sent)
            
            def check_demo2():
                if demo2.destroyed:
                    self.var_sent.set(demo2.entry+"*****Window Destroyed*****")
                    self.mylabel.config(fg="red")
                else:
                    self.master.after(100, check_demo2)
    
            check_demo2()
    
    app = Demo1()
    Last edited by dwblas; September 26th, 2013 at 09:44 PM.

IMN logo majestic logo threadwatch logo seochat tools logo