0

I am kind of new to OOP and have been making a few Tkinter applications in Python.

My way to create a GUI is to create only one class with all the graphical part in the constructor function and have instance methods for all the "commands" triggered within the constructor function.

#Example
class GUI:
   
    def __init__(self,master):
        # Code for buttons, frames commands etc.
    def command1(self):
        # Do stuff

Is there a way I can create multiple classes to make the code more readable? I know it will not affect the actual performance of the application and will still work the same way. Although I wanted to learn to write better more readable code and dividing everything into classes. My aim would be to create a base class for the graphical stuff and other (static)classes with various functions for when commands are called.

I tried to do the following using inheritance and had no success:

#Example

root = Tk()
root.geometry("400x350"

class GUI:
   
    def __init__(self,master):
        # Code for buttons, frames commands etc.
        # When calling a command specific_commands.command1()

class specific_commands(GUI):
    def __init__(self,master):
        super().__init__(self,master)
    def command1 (self):
        #Do stuff

GUI(root)

root.mainloop()


What would be your suggestion when trying to do this? Is there another better way I can do this?

Thank you in advance for the help!

2 Answers2

1

One simple way is to use mixins - classes that are designed to augment a base class rather than be used as standalone objects.

Notice how, in the following example, the commands in Commands are able to use self to refer to the base class (eg: self.name)

import tkinter as tk

class CommandsMixin:
    def command1(self):
        print(f"hello, {self.name}")

class GUI(CommandsMixin):
    def __init__(self, master):
        self.master = master
        self.name = "world"
        button = tk.Button(master, text="Click me", command=self.command1)
        button.pack()

root = tk.Tk()
gui = GUI(root)
root.mainloop()

You can use multiple classes as mixins. For example, you could have one class for I/O, one for dealing with external processes, etc. You just include all classes when you define the GUI class:

class GUI(CommandsMixin, OtherMixin):
    ...

For more information see What is a mixin and why is it useful?


Another solution is to leave the classes as distinct entities, then instantiate them and pass the entities around as arguments to the other classes that need them.

import tkinter as tk

class Commands:
    def __init__(self, master, gui):
        self.gui = gui
        self.master = master

    def command1(self):
        print(f"hello, {self.gui.name}")

class GUI():
    def __init__(self, master):
        self.master = master
        self.name = "world"
        self.commands = Commands(master=master, gui=self)
        button = tk.Button(master, text="Click me", command=self.commands.command1)
        button.pack()

root = tk.Tk()
gui = GUI(root)
root.mainloop()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
0

to create a base class for the graphical stuff and other (static)classes with various functions for when commands are called.

If I understand you correctly, you are looking for things called Mixin classes or in short mixins, it bundles a set of methods for reuse.

Daweo
  • 31,313
  • 3
  • 12
  • 25