GUI - Tkinter - MVC

news2024/11/17 14:47:20
  • 【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()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1955567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

灵活数据流处理:NeuronEX 支持 JavaScript 自定义函数

随着数据要素逐渐成为帮助工业企业提升智能化水平的重要助力,如何灵活采集和处理工业数据,并满足用户定制化的数据需求,成为企业数字化建设的焦点之一。 NeuronEX 是一款专为工业场景设计的边缘网关软件,具备工业设备数据采集、工…

@JSONField(format = “yyyyMMddHH“)的作用和使用

JySellerItqrdDataDO对象中的字段为: private Date crdat; 2.数据库中的相应字段为: crdat datetime DEFAULT NULL COMMENT 创建时间,2. 打印出的结果为: “crdat”:“2024072718” 年月日时分秒 3. 可以调整format的格式 4. 这样就把Date类…

信息搜集——小米

小米 主域名:www.miui.com 备案网站:27个 备案APP:21个 备案小程序:13个 备案公众号:23个 备案微博:43个 IP 域名 端口 状态码 Ping 网址 多地ping 网站名称 网址 域名 网站备案/许可证号 公 司名…

手撕数据结构---------顺序表和链表

1.线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中⼴泛使 ⽤的数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的⼀条直…

java实战项目--拼图小游戏(附带全套源代码)

个人主页VON 所属专栏java实战项目游戏参考黑马程序员 一、效果展示 二、功能介绍 游戏中所有的图片以及代码均已打包,玩家直接安装游戏即可,不用idea也可以畅玩。 游戏功能比较单一,只有简单的拼图功能。 a:展示原图重新游戏&a…

初涉JVM

JVM 字节码、类的生命周期、内存区域、垃圾回收 JVM主要功能: 解释运行(翻译字节码)内存管理(GC)即使编译(Just - In - Time, JIT) 将短时间内常使用到的字节码翻译成机器码存储在内…

whaler_通过镜像导出dockerfile

1、Whaler简介 Whaler:从镜像导出Dockerfile,whaler英文释义捕鲸船。 2、下载安装 # wget -cO /usr/local/bin/whaler https://github.com/P3GLEG/Whaler/releases/download/1.0/Whaler_linux_amd64 3、赋予可执行权限 [rootlocalhost ~]# chmod x /usr/local/…

Android OTA刷机包制作学习笔记

前言 OTA是一个再常见不过的需求,Android提供了recovery用于完成相关操作。 常规OTA包制作有两种: 有项目的完整AOSP源码,可以在成构建产物zip包后利用官方脚本制作。具体参阅:Office OTA假设你没有1的条件那么可以利用官方非A/…

exo-tinggrad 架构解析

目录 exo-tinggrad 架构解析 8B 模型配置 70B 模型配置 exo-tinggrad 架构解析 这个项目目录包含了一系列与Python相关的文件和文件夹,它们共同构成了一个可能的项目或库。这些文件和文件夹按照特定的命名和组织方式被放置在了一起,以便于管理、开发和维护。 tinygrad: 这…

24.7.28(tarjan 割点,割边,多重背包单调队列优化)

星期一: cf round 960 div2 B 简单构造 cf传送门 题意有点绕 思路:开始容易想到 y前和 x后全-1,y到x填1的构造,但对于 5 2 1,1 1 -1 -1 -1有问题,1和5的后缀值都为 -1…

【MySQL进阶之路 | 高级篇】简述Bin Log日志

1. 日志类型 MySQL有不同类型的日志文件,用来存储不同类型的日志,分为二进制日志、错误日志、通用查询日志和慢查询日志,这也是常用的4种。MySQL 8又新增两种支持的日志:中继日志和数据定义语句日志。使用这些日志文件,可以查看M…

树与二叉树【数据结构】

前言 之前我们已经学习过了各种线性的数据结构,顺序表、链表、栈、队列,现在我们一起来了解一下一种非线性的结构----树 1.树的结构和概念 1.1树的概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一…

LLM大模型在融合通信产品中的应用实践

前言 LLM 问题 幻觉:在没有答案的情况下提供虚假信息。 过时:当用户需要特定的当前响应时,提供过时或通用的信息。 来源:从非权威来源创建响应。由于术语混淆,不同的培训来源使用相同的术语来谈论不同的事情&#…

【Gin】智慧架构的巧妙砌筑:Gin框架中控制反转与依赖注入模式的精华解析与应用实战(下)

【Gin】智慧架构的巧妙砌筑:Gin框架中控制反转与依赖注入模式的精华解析与应用实战(下) 大家好 我是寸铁👊 【Gin】智慧架构的巧妙砌筑:Gin框架中控制反转与依赖注入模式的精华解析与应用实战(下)✨ 喜欢的小伙伴可以点点关注 💝 …

Meta 发布 Llama3.1,一站教你如何推理、微调、部署大模型

最近这一两周看到不少互联网公司都已经开始秋招提前批了。不同以往的是,当前职场环境已不再是那个双向奔赴时代了。求职者在变多,HC 在变少,岗位要求还更高了。 最近,我们又陆续整理了很多大厂的面试题,帮助一些球友解…

古文:诸葛亮《前出师表》

前出师表 师:军队。 表:就是“奏表”,又称“表文”,是臣属给君王的上书。古代给君王的上书,有各种名称,不同的名称与上书内容有关。刘勰《文心雕龙章表》云:“章以谢恩,奏以按劾&a…

高速板开源项目学习(二)

一定要找一个高速板写的详细的等长规范: 看的出来,这位小哥也是卡着嘉立创最小免费钻孔大小来打孔的: 这里的天线,他做了禁止铺铜和走线处理,模拟信号在这里容易遇到干扰,这样是正确的,值得去学…

解决使用selenium-wire访问链接地址不安全的问题

pip安装selenium-wire 描述:这里用的是python3.12.2 selenium-wire5.1.0 pip3.12 install selenium-wire pip3.12 install blinker1.7 pip3.12 install setuptools 运行以下命令来获取证书 python -m seleniumwire extractcert 安装浏览器ssl证书 Windows上给…

【JavaScript】延迟加载 js 脚本

defer 属性:在 HTML 中通过设置 script 标签的 defer 属性来实现脚本的延迟加载,即脚本的下载与 HTML 的解析不会阻塞彼此,脚本会在 HTML 解析完成后才执⾏。async 属性:在 HTML 中通过设置 script 标签的 async 属性来实现脚本的…

深入理解 Java NIO:ByteBuffer和MappedByteBuffer的特性与使用

目录 前言 ByteBuffer是什么 重要特点 分配缓冲区 读写模式切换 操作文本数据 操作基本数据类型 案例解析-循环输出数据 MappedByteBuffer是什么 MappedByteBuffer 的工作机制 刷盘时机 总结 前言 在深入学习 RocketMQ 这款高性能消息队列框架的源码时&#xff0c…