MVC(Model-View-Controller)framework using Python ,Tkinter and SQLite

项目结构

 sql:

1
2
3
4
5
CREATE TABLE IF NOT EXISTS School (
    SchoolId TEXT not null
    SchoolName TEXT NOT NULL,
    SchoolTelNo TEXT NOT NULL
)

  

整体思路
Model:负责与 SQLite 数据库进行交互,包括创建表、插入、删除、更新和查询数据等操作。
View:使用 Tkinter 和 ttk.Treeview 创建用户界面,包含输入框、按钮和分页控件,用于显示数据并处理用户的交互。
Controller:处理用户界面的事件,调用 Model 中的方法进行数据操作,并更新 View 中的显示。
代码实现:

Model 部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# encoding: utf-8
# 版权所有 2024 ©涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2023.1 python 3.11
# OS        : windows 10
# database  : mysql 9.0 sql server 2019, poostgreSQL 17.0  oracle 11g sqlite
# Datetime  : 2024-11-20 22:35:21
# database  :sql server 2019
# User      : geovindu
# Product   : PyCharm
# Project   : pySQLiteMvcDemo
# File      : bll/School.py
# explain   : 学习
from __future__ import annotations
from abc import ABC, abstractmethod
import os
import sys
from Model.school import SchoolInfo
from Factory.AbstractFactory import AbstractFactory
  
class SchoolBll(object):
    """
    学校表                   
    """
  
    dal = AbstractFactory.createSchool
    """
    类属性 接口DAL
    """
    def __init__(self):
        """
        """
        self.__name = "SchoolBll"
        self.createtable()  # 如果不存在,初始化表
  
   
  
    def __del__(self):
        """
        :return:
        """
        print(f"{self.__name} ERASE MEMORY")
  
    def Close(cls):
        """
        关闭
        :return:
        """
        cls.dal().Close()
  
    def createtable(self):
        """
        建表
        """
        self.dal().createtable()
  
  
    def selectData(self) -> list:
        """
        :return:
        """
        data = self.dal().selectSql()
        return data
  
  
    def select(self) -> list[SchoolInfo]:
        """
        :return:
        """
  
        schools = []
  
        data = self.dal().selectSql()
        if len(data) > 0:
            for SchoolId,SchoolName,SchoolTelNo in data[0]:
                info = SchoolInfo()
                info.SchoolId = SchoolId
                info.SchoolName = SchoolName
                info.SchoolTelNo = SchoolTelNo
                schools.append(info)
        return schools
  
    def selectSql(cls) -> list[SchoolInfo]:
        """
        元组数据
        :return: list 列表
        """
        schools = []
  
        data = cls.dal().selectSql()
        if len(data) > 0:
            for SchoolId,SchoolName,SchoolTelNo in data[0]:
                info=SchoolInfo()
                info.SchoolId = SchoolId
                info.SchoolName = SchoolName
                info.SchoolTelNo = SchoolTelNo
                schools.append(info)
        return schools
  
    def selectSqlCount(cls) -> int:
        """
        查询数据 总数
        :return:
        """
        #print(cls.dal().selectSqlCount()[0][0])
        total = cls.dal().selectSqlCount()[0][0]
        return total
  
    def Count(self) -> int:
        """
        查询数据 总数
        :return:
        """
        total = self.dal().selectSqlCount()[0][0]
        return total
  
  
    def getcount(cls, search_query=""):
        """
        计算
        :param search_query:
        :return:
        """
        return cls.dal().getcount(search_query)
  
  
    def getschools(cls, page, limit, search_query=""):
        """
        查询
        :param page:
        :param limit:
        :param search_query:
        :return:
        """
        data=cls.dal().getschools(page, limit, search_query)
        print("data:",data)
        return data
  
  
    def selectSqlOrder(cls, order: str) -> list[SchoolInfo]:
        """
        元组数据
        :param order: SchoolName desc/asc
        :return:
        """
        schools = []
        data = cls.dal().selectSqlOrder(order)
        if len(data) > 0:
            for SchoolId,SchoolName,SchoolTelNo in data[0]:
                info=SchoolInfo()
                info.SchoolId = SchoolId
                info.SchoolName = SchoolName
                info.SchoolTelNo = SchoolTelNo
                schools.append(info)
        return schools
  
  
    def selectSort(cls,field:str,isOrder:bool)->list[SchoolInfo]:
        """
        :param field SchoolId
        :param order:  desc/asc
        :return:
        """
        schools = []
        data = cls.dal().selectSort(field,isOrder)
        if len(data) > 0:
            for SchoolId,SchoolName,SchoolTelNo in data[0]:
                info = SchoolInfo()
                info.SchoolId = SchoolId
                info.SchoolName = SchoolName
                info.SchoolTelNo = SchoolTelNo
                schools.append(info)
        return schools
  
  
    def selectIdSql(cls,SchoolId:str) -> list[SchoolInfo]:
        """
        :param SchoolId:ID
        :return:
        """
        schools = []
        data = cls.dal().selectIdSql(SchoolId)
        #print(data)
        if len(data)>0:
            for SchoolId,SchoolName,SchoolTelNo in data[0]:
                info = SchoolInfo()
                info.SchoolId = SchoolId
                info.SchoolName = SchoolName
                info.SchoolTelNo = SchoolTelNo
                schools.append(info)
        return schools
  
    def addSql(cls,info:SchoolInfo) -> int:
        """
        :param info:实体类
        :return:
        """
        return cls.dal().addSql(info)
  
  
    def add(self,info:SchoolInfo) -> int:
        """
        :param info:实体类
        :return:
        """
        return self.dal().addSql(info)
  
  
    def editSql(cls,info:SchoolInfo) -> int:
        """
        :param info:实体类
        :return:
        """
        #print(info)
        return cls.dal().editSql(info)
  
    def edit(self,info:SchoolInfo) -> int:
        """
        :param info:实体类
        :return:
        """
        #print(info)
        return self.dal().editSql(info)
  
  
  
    def delSql(cls, SchoolId: str) -> int:
        """
        :param SchoolId:
        :return:
        """
        return cls.dal().delSql(SchoolId)
  
    def delinfo(self, SchoolId: str) -> int:
        """
        :param SchoolId:
        :return:
        """
        return self.dal().delSql(SchoolId)

  

View 部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2023.1 python 3.11
# OS        : windows 10
# database  : mysql 9.0 sql server 2019, poostgreSQL 17.0  oracle 21c Neo4j sqlite
# Datetime  : 2025/2/11 20:37
# User      : geovindu
# Product   : PyCharm
# Project   : pySQLiteMvcDemo
# File      : ViewUI/SchoolView.py
# explain   : 学习
  
import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
from Model.school import SchoolInfo
  
class SchoolView(tk.Frame):
    """
    View 类:负责创建和管理用户界面
    """
    def __init__(self, master=None):
        """
        :param master:
        """
        super().__init__(master)
  
        self.master = master
        self.pack()
        self.create_widgets()
  
    def create_widgets(self):
        """
        :return:
        """
        self.search_frame = tk.Frame(self)
        self.search_frame.pack(pady=10)
        # 搜索输入框
        self.search_label = tk.Label(self.search_frame, text="搜索:")
        #self.search_label.pack()
        self.search_label.grid(row=0, column=0)
        self.search_entry = tk.Entry(self.search_frame)
        #self.search_entry.pack()
        self.search_entry.grid(row=0, column=1)
        # 搜索按钮
        self.search_button = tk.Button(self.search_frame, text="搜索")
        #self.search_button.pack()
        self.search_button.grid(row=0, column=2)
  
        self.tree_frame = tk.Frame(self)
        self.tree_frame.pack(pady=10)
        # Treeview 控件
        self.tree = ttk.Treeview(self.tree_frame, columns=('ID', '校名', '电话'), show='headings')
        self.tree.heading('ID', text='ID')
        self.tree.heading('校名', text='校名')
        self.tree.heading('电话', text='电话')
        self.tree.pack()
  
        # Pagination Frame
        self.pagination_frame = tk.Frame(self)
        self.pagination_frame.pack(pady=10)
  
        # 分页控件
        self.prev_button = tk.Button(self.pagination_frame, text="上一页")
        self.prev_button.pack(side=tk.LEFT)
        self.page_label = tk.Label(self.pagination_frame, text="第 1 页")
        self.page_label.pack(side=tk.LEFT)
  
        self.pagetotal_label = tk.Label(self.pagination_frame, text="/共 1 条")
        self.pagetotal_label.pack(side=tk.LEFT)
  
        self.next_button = tk.Button(self.pagination_frame, text="下一页")
        self.next_button.pack(side=tk.LEFT)
  
        # Add/Update/Delete Frame
        self.action_frame = tk.Frame(self)
        self.action_frame.pack(pady=10)
        self.id_label = tk.Label(self.action_frame, text="編號:")
        #self.id_label.pack()
        self.id_label.grid(row=0, column=0)
  
        self.id_entry = tk.Entry(self.action_frame)
        self.id_entry.grid(row=0, column=1)
  
        # 校名输入框
        self.name_label = tk.Label(self.action_frame, text="校名:")
        self.name_label.grid(row=1, column=0)
  
        self.name_entry = tk.Entry(self.action_frame)
        self.name_entry.grid(row=1, column=1)
        # 电话输入框
        self.phone_label = tk.Label(self.action_frame, text="电话:")
        self.phone_label.grid(row=2, column=0)
        self.phone_entry = tk.Entry(self.action_frame)
        self.phone_entry.grid(row=2, column=1)
        # 添加按钮
        self.add_button = tk.Button(self.action_frame, text="添加")
        self.add_button.grid(row=3, column=0)
        # 修改按钮
        self.update_button = tk.Button(self.action_frame, text="修改")
        self.update_button.grid(row=3, column=1)
        # 删除按钮
        self.delete_button = tk.Button(self.action_frame, text="删除")
        self.delete_button.grid(row=3, column=2)
  
    def clear_entries(self):
        """
        :return:
        """
        self.id_entry.delete(0, tk.END)
        self.name_entry.delete(0, tk.END)
        self.phone_entry.delete(0, tk.END)
        self.search_entry.delete(0, tk.END)
  
    def populate_treeview(self, contacts):
        """
        :param contacts:
        :return:
        """
        for i in self.tree.get_children():
            self.tree.delete(i)
        for contact in contacts:
            self.tree.insert('', 'end', values=contact)
  
  
    def update_page_label(self, page, total_pages):
        """
        :param page:
        :param total_pages:
        :return:
        """
        self.page_label.config(text=f"第 {page} 页/共 {total_pages} 页")
  
    def update_page_total(self,tatal):
        """
        :param tatal:
        :return:
        """
        self.pagetotal_label.config(text=f"共{tatal} 条")
  
  
  
class AddSchoolWindow(tk.Toplevel):
    """
    弹出窗口 - 添加学校
    """
    def __init__(self, master, controller):
        """
        :param master:
        :param controller:
        """
        super().__init__(master)
        self.controller = controller
        self.title("添加学校")
        self.create_widgets()
    def create_widgets(self):
        """
        :return:
        """
        self.action_frame = tk.Frame(self)
        self.action_frame.pack(pady=10)
        # 学校 ID 输入框
        self.id_label = tk.Label(self.action_frame, text="学校 ID:")
        self.id_label.grid(row=0, column=0)
        self.id_entry = tk.Entry(self.action_frame)
        self.id_entry.grid(row=0, column=1)
        # 学校名称输入框
        self.name_label = tk.Label(self.action_frame, text="学校名称:")
        self.name_label.grid(row=1, column=0)
        self.name_entry = tk.Entry(self.action_frame)
        self.name_entry.grid(row=1, column=1)
        # 学校电话输入框
        self.tel_label = tk.Label(self.action_frame, text="学校电话:")
        self.tel_label.grid(row=2, column=0)
        self.tel_entry = tk.Entry(self.action_frame)
        self.tel_entry.grid(row=2, column=1)
        # 保存按钮
        self.save_button = tk.Button(self.action_frame, text="保存", command=self.save_school)
        self.save_button.grid(row=3, column=0)
    def save_school(self):
        """
        :return:
        """
        school_id = self.id_entry.get()
        school_name = self.name_entry.get()
        school_tel = self.tel_entry.get()
        info = SchoolInfo()
        info.SchoolId = school_id
        info.SchoolName = school_name
        info.SchoolTelNo = school_tel
  
        if school_id and school_name and school_tel:
            self.controller.add_school(info)
            self.destroy()
        else:
            messagebox.showerror("错误", "所有字段均为必填项")
  
  
  
class EditSchoolWindow(tk.Toplevel):
    """
    弹出窗口 - 修改学校
    """
    def __init__(self, master, controller, school_id, school_name, school_tel):
        """
        :param master:
        :param controller:
        :param school_id:
        :param school_name:
        :param school_tel:
        """
        super().__init__(master)
        self.controller = controller
        self.school_id = school_id
        self.title("修改学校")
        self.create_widgets(school_name, school_tel)
    def create_widgets(self, school_name, school_tel):
        """
        :param school_name:
        :param school_tel:
        :return:
        """
        self.action_frame = tk.Frame(self)
        self.action_frame.pack(pady=10)
        # 学校 ID 标签(不可编辑)
        self.id_label = tk.Label(self.action_frame, text="学校 ID:")
        self.id_label.grid(row=0, column=0)
        self.id_entry = tk.Entry(self.action_frame)
        self.id_entry.insert(0, self.school_id)
        self.id_entry.config(state='readonly')
        self.id_entry.grid(row=0, column=1)
        # 学校名称输入框
        self.name_label = tk.Label(self.action_frame, text="学校名称:")
        self.name_label.grid(row=1, column=0)
        self.name_entry = tk.Entry(self.action_frame)
        self.name_entry.insert(0, school_name)
        self.name_entry.grid(row=1, column=1)
        # 学校电话输入框
        self.tel_label = tk.Label(self.action_frame, text="学校电话:")
        self.tel_label.grid(row=2, column=0)
        self.tel_entry = tk.Entry(self.action_frame)
        self.tel_entry.insert(0, school_tel)
        self.tel_entry.grid(row=2, column=1)
        # 保存按钮
        self.save_button = tk.Button(self.action_frame, text="保存", command=self.save_school)
        self.save_button.grid(row=3, column=0)
  
  
    def save_school(self):
        """
        :return:
        """
  
        school_name = self.name_entry.get()
        school_tel = self.tel_entry.get()
        if school_name and school_tel:
            print("edit",self.school_id)
            info=SchoolInfo()
            info.SchoolId=self.school_id
            info.SchoolName=school_name
            info.SchoolTelNo=school_tel
            #self.controller.update_school(self.school_id, school_name, school_tel)
            self.controller.update_school(info)
            self.destroy()
        else:
            messagebox.showerror("错误", "所有字段均为必填项")

  

Controller 部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2023.1 python 3.11
# OS        : windows 10
# database  : mysql 9.0 sql server 2019, poostgreSQL 17.0  oracle 21c Neo4j sqlite
# Datetime  : 2025/2/11 20:36
# User      : geovindu
# Product   : PyCharm
# Project   : Controller/pySQLiteMvcDemo
# File      : SchoolController.py
# explain   : 学习
import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3
from Model.school import SchoolInfo
from BLLModel.school import SchoolBll
from ViewUI.SchoolView import AddSchoolWindow
from ViewUI.SchoolView import EditSchoolWindow
  
  
class SchoolController(object):
    """
    Controller 类:负责处理用户输入和更新模型和视图
    """
    def __init__(self, model, view):
        """
        :param model:
        :param view:
        """
        self.model = SchoolInfo()
        self.view = view
        self.current_page = 1
        self.limit = 10
        self.search_query = ""
        # 绑定按钮点击事件到相应的处理方法
        self.view.add_button.config(command=self.addschools)
        #self.view.add_button.config(command=self.open_add_window)
        self.view.update_button.config(command=self.updateschools)
        self.view.delete_button.config(command=self.deleteschools)
        self.view.search_button.config(command=self.searchschools)
        self.view.prev_button.config(command=self.prev_page)
        self.view.next_button.config(command=self.next_page)
  
        self.view.tree.bind("<Double-1>", self.open_edit_window)
        self.showschools()
        self.bll = SchoolBll()
  
    def open_add_window(self):
        """
        :return:
        """
        AddSchoolWindow(self.view.master, self)
  
    def open_edit_window(self, event):
        """
        :param event:
        :return:
        """
        selected_item = self.view.tree.selection()
        if selected_item:
            values = self.view.tree.item(selected_item)['values']
            school_id = values[0]
            school_name = values[1]
            school_tel = values[2]
            EditSchoolWindow(self.view.master, self, school_id, school_name, school_tel)
  
    def add_school(self, info:SchoolInfo):
        """
        :param info:
        :return:
        """
        self.bll.addSql(info)
        self.show_schools()
  
    def delete_school(self):
        """
        :return:
        """
        selected_item = self.view.tree.selection()
        if selected_item:
            school_id = self.view.tree.item(selected_item)['values'][0]
            self.bll.delSql(school_id)
            self.show_schools()
        else:
            messagebox.showerror("错误", "请选择要删除的学校")
  
    def update_school(self, info):
        """
        :param info:
        :return:
        """
        self.bll.editSql(info)
        self.show_schools()
  
    def search_schools(self):
        """
        :return:
        """
        self.search_query = self.view.search_entry.get()
        self.current_page = 1
        self.show_schools()
  
    def show_schools(self):
        """
        :return:
        """
        total_count = self.bll.getcount(self.search_query)[0][0]
        print(total_count)
        if total_count >= 1:
            total_pages = (total_count + self.limit - 1) // self.limit
            contacts = self.bll.getschools(self.current_page, self.limit, self.search_query)
            self.view.populate_treeview(contacts)
            self.view.update_page_label(self.current_page, total_pages)
            self.view.update_page_total(total_count)
  
  
    def addschools(self):
        """
        :return:
        """
        id = self.view.id_entry.get()
        name = self.view.name_entry.get()
        phone = self.view.phone_entry.get()
        self.model.SchoolId=id
        self.model.SchoolName=name
        self.model.SchoolTelNo=phone;
        if name and phone:
            self.bll.add(self.model)
            self.view.clear_entries()
            self.showschools()
        else:
            messagebox.showerror("错误", "校名和电话不能为空")
    def deleteschools(self):
        """
        :return:
        """
        selected_item = self.view.tree.selection()
        if selected_item:
            id = str(self.view.tree.item(selected_item)['values'][0])
            print("id",id)
            self.bll.delSql(id)
            self.showschools()
        else:
            messagebox.showerror("错误", "请选择要删除的联系人")
  
    def updateschools(self, event):
        """
        :return:
        """
        selected_item = self.view.tree.selection()
        if selected_item:
            id = str(self.view.tree.item(selected_item)['values'][0])
            #values = self.view.tree.item(selected_item)['values']
            name = self.view.name_entry.get()
            phone = self.view.phone_entry.get()
            self.model.SchoolId = id
            self.model.SchoolName = name
            self.model.SchoolTelNo = phone
            if name and phone:
                self.bll.editSql(self.model)
  
                self.view.clear_entries()
                self.showschools()
            else:
                messagebox.showerror("错误", "校名和电话不能为空")
        else:
            messagebox.showerror("错误", "请选择要修改的学校")
  
    def searchschools(self):
        """
        :return:
        """
        self.search_query = self.view.search_entry.get()
        self.current_page = 1
        self.showschools()
    def prev_page(self):
        """
        :return:
        """
        if self.current_page > 1:
            self.current_page -= 1
            self.showschools()
    def next_page(self):
        """
        :return:
        """
        total_count = self.bll.getcount(self.search_query)[0][0]
        total_pages = (total_count + self.limit - 1) // self.limit
        if self.current_page < total_pages:
            self.current_page += 1
            self.showschools()
    def showschools(self):
        """
        :return:
        """
        bll=SchoolBll()
        total_count = bll.getcount(self.search_query)[0][0]
        print(total_count)
        if total_count >= 1:
            total_pages = (total_count + self.limit - 1) // self.limit
            contacts = bll.getschools(self.current_page, self.limit, self.search_query)
            self.view.populate_treeview(contacts)
            self.view.update_page_label(self.current_page, total_pages)
            self.view.update_page_total(total_count)

  

调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author    : geovindu,Geovin Du 涂聚文.塗聚文
# IDE       : PyCharm Community Edition 2024.3 python 3.11
# OS        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  oracle 11g oracle 20c  Neo4j  sqlite
# Datetime  : 2025/2/11 20:11
# User      : geovindu
# Product   : PyCharm
# Project   : pySQLiteMVCDemo
# File      : main.py
# explain   : 学习
  
import tkinter as tk
from tkinter import ttk, messagebox
from BLLModel.school import SchoolBll
from ViewUI.SchoolView import SchoolView
from Controller.SchoolController import SchoolController
  
  
if __name__ == '__main__':
    """
     
    """
    root = tk.Tk()
    bllmodel = SchoolBll()
    view = SchoolView(master=root)
    controller = SchoolController(bllmodel, view)
    root.title("School Management")
    root.iconbitmap('favicon.ico')
    root.mainloop()

  

输出:

 

posted @   ®Geovin Du Dream Park™  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
历史上的今天:
2023-02-11 CSharp: XML Serialize and Deserialize
2015-02-11 csharp:SQLite and Access using C# code read data
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示