So! I'm building a GUI for an application I'm currently developing and I'm having a bit of trouble figuring out an issue. I'll try to explain it as best as I can in the code lines. Basically, I built a class to handle the initial window for the program, but if you read the code to the last line (I've snipped some of the code to get to the point), what I'm trying to do is mimic the first class I built so it shows a whole new window with the input, button, and text fields, as well as the labels. However, it never turns out quite right and the labels never print to the new tkinter window? Thoughts on how to put a class inside a class to do the same thing spkgui_tk(Tkinter.Tk) does?

Thanks ahead of time! If you have questions, just let me know! :)

import Tkinter
from fabric.api import * 

class spkgui_tk(Tkinter.Tk):
    '''Builds the shell for the program'''
    def __init__(self, parent): 
        Tkinter.Tk.__init__(self, parent) 
        self.parent = parent 
        self.initialize()

    def initialize(self):
        # main gui window
        self.grid() 

        # default stdout text field
        stdout = Tkinter.Text(self, autoseparators=True, height=10, width=50, wrap=Tkinter.WORD)
        stdout.grid(column=0, row= 15,  padx=10, pady=10, sticky="EW", columnspan=2,rowspan=2) 
        _inittext_ = "Welcome to the best damn program manager on the planet!" 
        stdout.insert(Tkinter.END, _inittext_) 
        stdout.see(Tkinter.END) 

        # entry fields 
        self.entryVariable = Tkinter.StringVar() 
        self.entry = Tkinter.Entry(self, textvariable = self.entryVariable) 
        self.entry.grid(column=0, row=0, sticky="EW") 
        self.entry.bind("<Return>",  self.OnPressEnter)  #bound to return, calls OnPressEnter method 
        self.entryVariable.set(u"Choose an option.") 

        # buttons (maybe change the font and the size later?) 
        button = Tkinter.Button(self, text="Exit",command=self.OnButtonClick, width=15) 
        button.grid(column=1,row=0) 

        # labels 
        self.labelVariable = Tkinter.StringVar() 
        label = Tkinter.Label(self, textvariable = self.labelVariable, anchor = "w", fg="white", bg= "grey") 
        label.grid(column=0, row=1, columnspan = 2, sticky = "EW") 
        self.labelVariable.set(u"1. Erase")

        self.labelVariable = Tkinter.StringVar() 
        label = Tkinter.Label(self, textvariable = self.labelVariable, anchor = "w", fg="black", bg = "white")
        label.grid(column=0, row=2, columnspan = 2, sticky = "EW") 
        self.labelVariable.set(u"2. Echo Path")  

        <--snipped--> 

        self.grid_columnconfigure(0, weight=1) 
        self.resizable(True,False) 
        self.update() 
        self.geometry(self.geometry()) 
        self.entry.focus_set() 
        self.entry.selection_range(0, Tkinter.END) 

    def OnButtonClick(self):
        self.destroy() 

        #### On Press Enter (from self window) ###### 
    def OnPressEnter(self, event):
        catch_command = int(self.entryVariable.get()) 

        catch_command = int(self.entryVariable.get()) 

        if catch_command == 1:
            erase() 
            stdout = Tkinter.Text(self, autoseparators=True, height=10, width=50, wrap=Tkinter.WORD) 
            stdout.grid(column=0, row= 15,  padx=10, pady=10, sticky="EW", columnspan=2,rowspan=2)  
            stext = "Erases bits and pieces from your trash can." 
            stdout.insert(Tkinter.END, stext) 
            stdout.see(Tkinter.END)

        <--snipped--> 

        if catch_command == 3:
            the problem in question. :/ 

That is more code than I want to trudge through for a simple question, so will just say that generally you use Toplevels as the code below illustrates. If there is more that you wish to know, post back. Note that you can use a function or third class to call (separate instance) each class as many times as you want, with individual parameters.

class one():
    def __init__(self, root):
        self.root = root
        top = tk.Toplevel(root)
        top.title("First")
        top.geometry("150x75+10+10")

        tk.Button(top, text="open new window", command=self.openit).grid()
        tk.Button(top, text="Quit", command=self.root.quit).grid(row=1)

    def openit(self):
        two = Two(self.root)

class Two():
    def __init__(self, root):
        self.root = root
        top = tk.Toplevel(root)
        top.title("Second")
        top.geometry("150x50+10+125")

        tk.Label(top, text="second window").grid()

root = tk.Tk()
root.withdraw()
one(root)
root.mainloop()

Edited 3 Years Ago by woooee

That sounds exactly like what I'm looking for my good sir, I will try that out here in a bit and let you know how it went. :)

So, I tried to implement the top level class as you noted, but I couldnt get that to work. So I reverted back to just putting a class within my main class, and everything is fine...its just the entry variable (self.entry) and the label variables are not showing. It's like the set attribute isn't catching, because It wont print the text widget data either. Any thoughts?

if catch_command == 3:
            class CommandShell_Internet(Tkinter.Tk): 
                '''class for catch command shell, InternetSettings object.'''
                def __init__(self, child): 
                    Tkinter.Tk.__init__(self, child) 
                    self.child = child 
                    self.re_initialize() 

                def re_initialize(self): 
                    self.grid() 

                    # re_initialize text widget 
                    reinit_output = Tkinter.Text(self, autoseparators=True, height=10, width=50, wrap=Tkinter.WORD)
                    reinit_output.grid(column=0, row= 15,  padx=10, pady=10, sticky="EW", columnspan=2,rowspan=2) 
                    #reinit_text="Welcome to the best damn program manager on the planet!"
                    #reinit_text.insert(Tkinter.END, reinit_text)  
                    #reinit_text.see(Tkinter.END) 

                    # re_initialize entry widget 
                    self.entryVariable = Tkinter.StringVar() 
                    self.entry = Tkinter.Entry(self, textvariable = self.entryVariable) 
                    self.entry.grid(column=0, row=0, sticky="EW") 
                    self.entry.bind("<Return>",  self.OnPressEnter)   
                    self.entryVariable.set(u"Choose an internet option.") 


                    # re_initialize button widget 
                    button = Tkinter.Button(self, text="Exit",command=self.OnButtonClick, width=15) 
                    button.grid(column=1,row=0) 

                    # re_initialize label widgets 
                    self.labelVariable = Tkinter.StringVar() 
                    label = Tkinter.Label(self, textvariable = self.labelVariable, anchor = "w", fg="black", bg= "grey") 
                    label.grid(column=0, row=1, columnspan = 2, sticky = "EW") 
                    self.labelVariable.set("o")


                ###### OnButtonClick (from CommandShell_Internet window) #######
                def OnButtonClick(self):
                    self.destroy() 

                ###### On PressEnter (from CommandShell_Internet window) ########   
                def OnPressEnter(self, event):
                    print self.entry






                    self.grid_columnconfigure(0, weight=1) 
                    self.resizable(True,False) 
                    self.update() 
                    self.geometry(self.geometry()) 
                    self.entry.focus_set() 
                    self.entry.selection_range(0, Tkinter.END)

            internetuserinterface = CommandShell_Internet(None)
            internetuserinterface.title("Internet Settings") 
            internetuserinterface.mainloop() 
This question has already been answered. Start a new discussion instead.