- 【python】 @property属性详解_python @property-CSDN博客
- Tkinter MVC (pythontutorial.net)
- GUI架构演进之MVC(一) - frydsh - 博客园 (cnblogs.com)
- MVC 模式 | 菜鸟教程 (runoob.com)
- MVC 架构详解 (freecodecamp.org)
- Python之MVC - chenbiao - SegmentFault 思否
- 利用MVC设计模式构建GUI(PyQt5版) - 知乎 (zhihu.com)
- PyQt5通过信号实现MVC的示例_python_脚本之家 (jb51.net)
1.MVC
- Model: The backend that contains all the data logic
-
A model in MVC represents the data. A model deals with getting data from or writing data into storage such as a database or file. The model may also contain the logic to validate the data to ensure data integrity.
The model must not depend on the view and controller. In other words, you can reuse the model in other non-Tkinter applications such as web and mobile apps.
-
- View: The frontend or graphical user interface (GUI)
-
A view is the user interface that represents the data in the model. The view doesn’t directly communicate with the model. Ideally, a view should have very little logic to display data.
The view communicates with the controller directly. In Tinker applications, the view is the root window that consists of widgets.
-
- Controller: The brains of the application that controls how data is displayed
-
controller acts as the intermediary between the views and models. The controller routes data between the views and models.
For example, if users click the save button on the view, the controller routes the “save” action to the model to save the data into a database and notify the view to display a message.
-
2.demo
import re
import tkinter as tk
from tkinter import ttk
class Model:
def __init__(self, email):
self.email = email
@property
def email(self):
return self.__email
@email.setter
def email(self, value):
"""
Validate the email
:param value:
:return:
"""
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
if re.fullmatch(pattern, value):
self.__email = value
else:
raise ValueError(f'Invalid email address: {value}')
def save(self):
"""
Save the email into a file
:return:
"""
with open('emails.txt', 'a') as f:
f.write(self.email + '\n')
class View(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
# create widgets
# label
self.label = ttk.Label(self, text='Email:')
self.label.grid(row=1, column=0)
# email entry
self.email_var = tk.StringVar()
self.email_entry = ttk.Entry(self, textvariable=self.email_var, width=30)
self.email_entry.grid(row=1, column=1, sticky=tk.NSEW)
# save button
self.save_button = ttk.Button(self, text='Save', command=self.save_button_clicked)
self.save_button.grid(row=1, column=3, padx=10)
# message
self.message_label = ttk.Label(self, text='', foreground='red')
self.message_label.grid(row=2, column=1, sticky=tk.W)
# set the controller
self.controller = None
def set_controller(self, controller):
"""
Set the controller
:param controller:
:return:
"""
self.controller = controller
def save_button_clicked(self):
"""
Handle button click event
:return:
"""
if self.controller:
self.controller.save(self.email_var.get())
def show_error(self, message):
"""
Show an error message
:param message:
:return:
"""
self.message_label['text'] = message
self.message_label['foreground'] = 'red'
self.message_label.after(3000, self.hide_message)
self.email_entry['foreground'] = 'red'
def show_success(self, message):
"""
Show a success message
:param message:
:return:
"""
self.message_label['text'] = message
self.message_label['foreground'] = 'green'
self.message_label.after(3000, self.hide_message)
# reset the form
self.email_entry['foreground'] = 'black'
self.email_var.set('')
def hide_message(self):
"""
Hide the message
:return:
"""
self.message_label['text'] = ''
class Controller:
def __init__(self, model, view):
self.model = model
self.view = view
def save(self, email):
"""
Save the email
:param email:
:return:
"""
try:
# save the model
self.model.email = email
self.model.save()
# show a success message
self.view.show_success(f'The email {email} saved!')
except ValueError as error:
# show an error message
self.view.show_error(error)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title('Tkinter MVC Demo')
# create a model
model = Model('hello@pythontutorial.net')
# create a view and place it on the root window
view = View(self)
view.grid(row=0, column=0, padx=10, pady=10)
# create a controller
controller = Controller(model, view)
# set the controller to view
view.set_controller(controller)
if __name__ == '__main__':
app = App()
app.mainloop()