Since Python’s Tk widgets are classes, it is really easy to compose GUIs by using Pythons OOP capabilities. OOP works really well because we can break complex GUIs down into smaller components and then compose a larger GUI out of these components. Let’s begin with a text area control.
from tkinter import *
class TextArea(Text):
def __init__(self, parent=None):
Text.__init__(self, parent, width=40, height=10, border=2)
self.pack(expand=YES, fill=BOTH, side=TOP)
if __name__ == '__main__':
TextArea(Toplevel())
mainloop()
This code subclasses the Text control and initializes it to what would be a reasonably sized text area control that grows and shrinks with the window. We can verify if our control is working properly by using the self-test code found in the script. Here is a screenshot of what it looks like.

It’s not much of a window, but we aren’t done composing our GUI yet either. Now let’s make some buttons that will let us load, save, and quit the application. The buttons will be arranged horizontally from left to right. This time, we are going to subclass the Frame class.
class ControlPanel(Frame):
def __init__(self, parent=None, save=None, load=None, quit_command=exit):
Frame.__init__(self, parent)
Button(self, text='Save', command=save).pack(side=LEFT)
Button(self, text='Load', command=load).pack(side=LEFT)
Button(self, text='Exit', command=quit_command).pack(side=LEFT)
self.pack(expand=YES, fill=BOTH, side=TOP)
if __name__ == '__main__':
ControlPanel(Toplevel())
mainloop()
In this example, we are using the self
variable as a parent object to our 3 objects. The ControlPanel’s constructor accepts three references to functions that act as event handlers for the buttons. Inside of the constructor, we create three buttons and set their text and command attributes. Then we pack them to the left side of the layout. Finally, the frame itself is packed. Running the self-test code gives us the following window.

The final task is to combine our controls into a single window. Once again, we are going to subclass Frame.
class TextPanel(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)
TextArea(self)
ControlPanel(self)
self.pack(expand=YES, fill=BOTH)
if __name__ == '__main__':
TextPanel(Toplevel())
mainloop()
Notice how the TextPanel class simply uses TextArea and ControlPanel. Once again, we are using composition to build up a complex GUI. The beauty of this pattern is that we can use both TextArea and ControlPanel in other GUIs. Futhermore, the TextPanel class can also get embedded into other GUIs as well.
Since all three classes have test code, we can easily see how our code is working as we develop. This is part of the reason why it’s so easy to build up GUI applications in Python using Tk or another widget toolkit. We can easily contruct GUIs using OOP and then test then instantly and independently of the application.
Here is the finished GUI followed by a complete script.

from tkinter import *
class TextArea(Text):
def __init__(self, parent=None):
Text.__init__(self, parent, width=40, height=10, border=2)
self.pack(expand=YES, fill=BOTH, side=TOP)
class ControlPanel(Frame):
def __init__(self, parent=None, save=None, load=None, quit_command=exit):
Frame.__init__(self, parent)
Button(self, text='Save', command=save).pack(side=LEFT)
Button(self, text='Load', command=load).pack(side=LEFT)
Button(self, text='Exit', command=quit_command).pack(side=LEFT)
self.pack(expand=YES, fill=BOTH, side=TOP)
class TextPanel(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)
TextArea(self)
ControlPanel(self)
self.pack(expand=YES, fill=BOTH)
if __name__ == '__main__':
TextArea(Toplevel())
ControlPanel(Toplevel())
TextPanel(Toplevel())
mainloop()
Like this:
Like Loading...