How to Create a Simple MVC App in Tkinter

The Model-View-Controller (MVC) pattern is a classic architecture that helps separate concerns in GUI applications. In this post, we’ll walk through how to build a simple counter app using Tkinter in Python, structured around the MVC pattern.

What We’re Building

A basic app with a number display and a button. Every time the button is clicked, the number increases by one.


Why Use MVC?

  • Model: Manages the data and logic.
  • View: Handles the GUI display.
  • Controller: Connects user actions to updates in the Model and View.

Step 1: Create the Model

The Model stores the data and handles the logic. For our counter app, it just needs to store a number and increment it.

# model.py
class CounterModel:
    def __init__(self):
        self._count = 0

    def increment(self):
        self._count += 1

    def get_count(self):
        return self._count

Step 2: Create the View

The View is responsible for the user interface. It shows the current count and has a button the user can press.

# view.py
import tkinter as tk

class CounterView(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Simple MVC Counter")

        self.label = tk.Label(self, text="0", font=("Arial", 24))
        self.label.pack(pady=20)

        self.button = tk.Button(self, text="Increment", font=("Arial", 14))
        self.button.pack()

    def set_controller(self, controller):
        self.button.config(command=controller.increment_counter)

    def update_count(self, count):
        self.label.config(text=str(count))

Step 3: Create the Controller

The Controller acts as a bridge between the View and the Model. It handles the logic when the button is clicked.

# controller.py
from model import CounterModel
from view import CounterView

class CounterController:
    def __init__(self, model, view):
        self.model = model
        self.view = view
        self.view.set_controller(self)

    def increment_counter(self):
        self.model.increment()
        new_count = self.model.get_count()
        self.view.update_count(new_count)

Step 4: Hook Everything Together

Now, create a simple app.py file to initialize the MVC components and start the app.

# app.py
from model import CounterModel
from view import CounterView
from controller import CounterController

def main():
    model = CounterModel()
    view = CounterView()
    controller = CounterController(model, view)

    view.mainloop()

if __name__ == "__main__":
    main()

Step 5: Run

Make sure all files (model.py, view.py, controller.py, and app.py) are in the same directory. Then run:

python app.py

Step 6: Complete Code

# model.py
class CounterModel:
    def __init__(self):
        self._count = 0

    def increment(self):
        self._count += 1

    def get_count(self):
        return self._count


# view.py
import tkinter as tk

class CounterView(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Simple MVC Counter")
        self.geometry("300x200")

        self.label = tk.Label(self, text="0", font=("Arial", 24))
        self.label.pack(pady=20)

        self.button = tk.Button(self, text="Increment", font=("Arial", 14))
        self.button.pack()

    def set_controller(self, controller):
        self.button.config(command=controller.increment_counter)

    def update_count(self, count):
        self.label.config(text=str(count))


# controller.py
class CounterController:
    def __init__(self, model, view):
        self.model = model
        self.view = view
        self.view.set_controller(self)

    def increment_counter(self):
        self.model.increment()
        new_count = self.model.get_count()
        self.view.update_count(new_count)


# app.py
def main():
    model = CounterModel()
    view = CounterView()
    controller = CounterController(model, view)

    view.mainloop()

if __name__ == "__main__":
    main()

Leave a Reply

Your email address will not be published. Required fields are marked *