Python, using tkinter how to customize where classes of ui components are displayed?
Question: I am very new to python, and am currently trying to organize my tkinter app in
a slightly different way. I'm trying to use classes to make the app more
modular and be able to use methods in the class in multiple places in the app.
Here is the updated code that I have:

    
    
    from tkinter import *
    
    
    class Application(Frame):
    
        def __init__(self, master=None):
            Frame.__init__(self, master)
            self.pack()
            self.createWidgets()
    
            self.QUIT.pack(side=LEFT)
            self.hi_there.pack(side=RIGHT)
    
            Frame.__init__(self, master)
            self.pack()
            self.createAnotherWidget()
    
            self.title_label.pack(side=LEFT)
            self.title_entry.pack(side=RIGHT)
    
        def say_hi(self):
            print("hi there, everyone!")
    
        def createWidgets(self):
            self.QUIT = Button(self)
            self.QUIT["text"] = "QUIT"
            self.QUIT["fg"]   = "red"
            self.QUIT["command"] =  self.quit
    
            self.hi_there = Button(self)
            self.hi_there["text"] = "Hello",
            self.hi_there["command"] = self.say_hi
    
    
        def createAnotherWidget(self):
            self.title_label = Label(self)
            self.title_label["text"] = "Title: "
            self.title_entry = Entry(self)
    
        def __init__(self, master=None):
            Frame.__init__(self, master)
            self.pack()
            self.createWidgets()
            self.createAnotherWidget()
    
    root = Tk()
    app = Application(master=root)
    app.mainloop()
    root.destroy()
    

This runs without errors, but nothing shows in the window. How can I customize
where the code for these methods will be placed when rendered? For this
example, I'm simply wanting the `createAnotherWidget` to display below the two
buttons in `createWidgets`


Answer: One solution is to have the caller be responsible for calling `pack` or `grid`
on the individual widgets. This requires that you save references to the
widgets somehow, such as attributes of the object. You do this already for
some widgets, but not for others. You need to be consistent.

Do this by moving the calls to `pack()` from the functions and into your
`__init__`:

    
    
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()
        self.createAnotherWidget()
    
        self.QUIT.pack(...)
        self.hi_there.pack(...)
        self.title_label.pack(...)
        self.title_entry.pack(...)
    

Of course, you'll need to modify `createAnotherWidget` to save references to
the widgets.

The point being, _creating_ widgets and _laying out widgets on the screen_ are
two separate problems that should be solved separately.

* * *

That being said, it's a bit unusual to have functions that create multiple
widgets that are designed to be stitched together by some other function.

A more common pattern is for functions to create widgets that are related, and
to manage the layout of the related widgets itself. That way the caller only
has to worry about organizing the groups of widgets rather than a bunch of
individual widgets.

For example, you might have one function that creates a toolbar. Another that
creates the main area with scrollbars. Another function would create a footer.
Another that creates a form with a bunch of label and entry widgets. Another
one that creates a label/entry combination. And so on.

