python: SQLAlchemy (ORM) Simple example using mysql in Ubuntu 24.04
mysql sql script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | create table School 表 ( `SchoolId` char (5) NOT NULL comment '主鍵primary key,學校編號' , `SchoolName` nvarchar(500) NOT NULL DEFAULT '' comment ' 學校名稱' , `SchoolTelNo` varchar (8) NULL DEFAULT '' comment '電話號碼' , PRIMARY KEY (SchoolId) #主鍵 )COMMENT= '學校表 School Table' DEFAULT CHARSET=utf8; create table Teacher ( `TeacherId` char (5) NOT NULL comment '主鍵primary key,老师編號' , `TeacherFirstName` nvarchar(100) NOT NULL DEFAULT '' comment ' 名' , `TeacherLastName` nvarchar(20) NOT NULL DEFAULT '' comment ' 姓' , `TeacherGender` char (2) NOT NULL DEFAULT '' comment '性別' , `TeacherTelNo` varchar (8) NULL DEFAULT '' comment '電話號碼' , `TeacherSchoolId` char (5) NOT NULL DEFAULT '' comment '外鍵 foreign key 學校ID' , PRIMARY KEY (TeacherId), #主鍵 FOREIGN KEY (TeacherSchoolId) REFERENCES School(SchoolId) #外鍵 )COMMENT= '老師表Teacher Table' DEFAULT CHARSET=utf8; |
项目结构
领域层(Domain Layer)
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 | # encoding: utf-8 # 版权所有 2025 ©涂聚文有限公司 ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述: # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 3.11 # OS : Ubuntu 24.0 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 oracle 21c Neo4j # Datetime : 2025/2/20 20:23 # User : geovindu # Product : PyCharm # Project : pyMySqlDDDOrmDemo # File : domain/entities/school.py # explain : 学习 '' ' create table School 表 ( `SchoolId` char(5) NOT NULL comment' 主鍵 primary key ,學校編號 ', `SchoolName` nvarchar(500) NOT NULL DEFAULT ' ' comment' 學校名稱 ', `SchoolTelNo` varchar(8) NULL DEFAULT ' ' comment' 電話號碼 ', PRIMARY KEY (SchoolId) #主鍵 )COMMENT=' 學校表 School Table ' DEFAULT CHARSET=utf8; ' '' class School: "" " 领域层(Domain Layer) 定义业务实体 " "" def __init__(self, school_id, school_name, school_tel_no): "" " :param school_id: 學校編號 :param school_name: 學校名稱 :param school_tel_no:電話號碼 " "" self.school_id = school_id self.school_name = school_name self.school_tel_no = school_tel_no # encoding: utf-8 # 版权所有 2025 ©涂聚文有限公司 ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述: # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 3.11 # OS : Ubuntu 24.0 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 oracle 21c Neo4j # Datetime : 2025/2/20 20:27 # User : geovindu # Product : PyCharm # Project : pyMySqlDDDOrmDemo # File : domain/repositories/school.py # explain : 学习 from abc import ABC, abstractmethod from typing import List from ..entities.school import School class SchoolRepository(ABC): "" " 领域层(Domain Layer) 存储库接口 " "" @abstractmethod def add (self, school: School): pass @abstractmethod def update (self, school: School): pass @abstractmethod def delete (self, school_id: str): "" " 删除 :param school_id: :return: " "" pass def get_schoolall(self) -> List[School]: "" " 所有 :return: " "" pass @abstractmethod def get_all(self, page: int , page_size: int , search_query: str = "" ) -> List[School]: "" " 分页 :param page: :param page_size: :param search_query: :return: " "" pass @abstractmethod def get_total_count(self, search_query: str = "" ) -> int : pass |
基础设施层(Infrastructure Layer)
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 | # encoding: utf-8 # 版权所有 2025 ©涂聚文有限公司 ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述: # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 3.11 # OS : Ubuntu 24.0 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 oracle 21c Neo4j # Datetime : 2025/2/20 20:46 # User : geovindu # Product : PyCharm # Project : pyMySqlDDDOrmDemo # File : infrastructure/model/school.py # explain : 学习 from sqlalchemy import create_engine, Column, String, ForeignKey from sqlalchemy.orm import sessionmaker, declarative_base, relationship Base = declarative_base() class SchoolModel(Base): """ 基础设施层(Infrastructure Layer) 数据库交互 分开会报错 """ __tablename__ = 'School' SchoolId = Column(String( 5 ), primary_key = True ) SchoolName = Column(String( 500 ), nullable = False , default = '') SchoolTelNo = Column(String( 8 ), nullable = True , default = '') teachers = relationship( "TeacherModel" , back_populates = "school" ) class TeacherModel(Base): """ 基础设施层(Infrastructure) 数据库交互 """ __tablename__ = 'Teacher' TeacherId = Column(String( 5 ), primary_key = True ) TeacherFirstName = Column(String( 100 ), nullable = False , default = '') TeacherLastName = Column(String( 20 ), nullable = False , default = '') TeacherGender = Column(String( 2 ), nullable = False , default = '') TeacherTelNo = Column(String( 8 ), nullable = True , default = '') TeacherSchoolId = Column(String( 5 ), ForeignKey( 'School.SchoolId' ), nullable = False , default = '') school = relationship( "SchoolModel" , back_populates = "teachers" ) # encoding: utf-8 # 版权所有 2025 ©涂聚文有限公司 ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述: # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 3.11 # OS : Ubuntu 24.0 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 oracle 21c Neo4j # Datetime : 2025/2/20 20:46 # User : geovindu # Product : PyCharm # Project : pyMySqlDDDOrmDemo # File : infrastructure/repositories/school.py # explain : 学习 from sqlalchemy import create_engine, Column, String, ForeignKey from sqlalchemy.orm import sessionmaker, declarative_base, relationship from domain.entities.school import School from ..model.school import SchoolModel from ..database.mysqlHelper import MysqlHeler from typing import List class SchoolRepository: """ 基础设施层(Infrastructure Layer) 实现存储库接口 """ def __init__( self ): """ """ self ._Session = MysqlHeler() def add( self , school: School): """ :param school: :return: """ session = self ._Session.getSession() school_model = SchoolModel(SchoolId = school.school_id, SchoolName = school.school_name, SchoolTelNo = school.school_tel_no) session.add(school_model) session.commit() session.close() def update( self , school: School): """ :param school: :return: """ session = self ._Session.getSession() school_model = session.query(SchoolModel).filter_by(SchoolId = school.school_id).first() if school_model: school_model.SchoolName = school.school_name school_model.SchoolTelNo = school.school_tel_no session.commit() session.close() def delete( self , school_id: str ): """ :param school_id: :return: """ session = self ._Session.getSession() school_model = session.query(SchoolModel).filter_by(SchoolId = school_id).first() if school_model: session.delete(school_model) session.commit() session.close() def get_schoolall( self ) - > List [School]: """ 查询所有所学校 :return: """ session = self ._Session.getSession() query = session.query(SchoolModel). all () ''' li=[School(school.SchoolId, school.SchoolName, school.SchoolTelNo) for school in query] for i in li: print(i.school_id,i.school_name,i.school_tel_no) print("query", [School(school.SchoolId, school.SchoolName, school.SchoolTelNo) for school in query]) ''' session.close() return [School(school.SchoolId, school.SchoolName, school.SchoolTelNo) for school in query] def get_all( self , page: int , page_size: int , search_query: str = "") - > List [School]: """ :param page: :param page_size: :param search_query: :return: """ session = self ._Session.getSession() query = session.query(SchoolModel) if search_query: query = query. filter ( (SchoolModel.SchoolId.contains(search_query)) | (SchoolModel.SchoolName.contains(search_query)) | (SchoolModel.SchoolTelNo.contains(search_query)) ) offset = (page - 1 ) * page_size school_models = query.offset(offset).limit(page_size). all () session.close() return [School(school.SchoolId, school.SchoolName, school.SchoolTelNo) for school in school_models] def get_total_count( self , search_query: str = ""): """ :param search_query: :return: """ session = self ._Session.getSession() query = session.query(SchoolModel) if search_query: query = query. filter ( (SchoolModel.SchoolId.contains(search_query)) | (SchoolModel.SchoolName.contains(search_query)) | (SchoolModel.SchoolTelNo.contains(search_query)) ) count = query.count() session.close() return count |
应用层(Application Layer)
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 | # encoding: utf-8 # 版权所有 2025 ©涂聚文有限公司 ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述: # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 3.11 # OS : Ubuntu 24.0 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 oracle 21c Neo4j # Datetime : 2025/2/20 20:04 # User : geovindu # Product : PyCharm # Project : pyMySqlDDDOrmDemo # File : application/services/school.py # explain : 学习 from typing import List from domain.entities.school import School from domain.repositories.school import SchoolRepository class SchoolService: """ 应用层(Application Layer) 封装业务逻辑。 """ def __init__( self , repository: SchoolRepository): """ :param repository: """ self .repository = repository def add_school( self , school: School): """ :param school: :return: """ self .repository.add(school) def update_school( self , school: School): """ :param school: :return: """ self .repository.update(school) def delete_school( self , school_id: str ): """ :param school_id: :return: """ self .repository.delete(school_id) def get_schoolall( self ) - > List [School]: """ 所有 :return: """ return self .repository.get_schoolall() def get_schools( self , page: int , page_size: int , search_query: str = "") - > List [School]: """ :param page: :param page_size: :param search_query: :return: """ return self .repository.get_all(page, page_size, search_query) def get_total_school_count( self , search_query: str = "") - > int : """ :param search_query: :return: """ return self .repository.get_total_count(search_query) |
表现层(Presentation Layer)
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 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | # encoding: utf-8 # 版权所有 2025 ©涂聚文有限公司 ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述: # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 3.11 # OS : Ubuntu 24.0 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 oracle 21c Neo4j # Datetime : 2025/2/20 20:47 # User : geovindu # Product : PyCharm # Project : pyMySqlDDDOrmDemo # File : presentation/views/school.py # explain : 学习 import tkinter as tk from tkinter import ttk class SchoolView( object ): """ 表现层(Presentation Layer) 包含视图和控制器,处理用户界面和操作。 """ def __init__( self , parent): """ :param parent: """ self .frame = tk.Frame(parent) # 搜索框 self .search_frame = ttk.Frame( self .frame) self .search_frame.pack(pady = 10 ) self .search_entry = ttk.Entry( self .search_frame) self .search_entry.pack(side = tk.LEFT, padx = 5 ) self .search_button = ttk.Button( self .search_frame, text = "Search" ) self .search_button.pack(side = tk.LEFT) # Treeview self .tree = ttk.Treeview( self .frame, columns = ( 'SchoolId' , 'SchoolName' , 'SchoolTelNo' ), show = 'headings' ) self .tree.heading( 'SchoolId' , text = 'School ID' ) self .tree.heading( 'SchoolName' , text = 'School Name' ) self .tree.heading( 'SchoolTelNo' , text = 'School Tel No' ) self .tree.pack(pady = 10 ) # 操作按钮 self .button_frame = ttk.Frame( self .frame) self .button_frame.pack(pady = 10 ) self .add_button = ttk.Button( self .button_frame, text = "Add" ) self .add_button.pack(side = tk.LEFT, padx = 5 ) self .edit_button = ttk.Button( self .button_frame, text = "Edit" ) self .edit_button.pack(side = tk.LEFT, padx = 5 ) self .delete_button = ttk.Button( self .button_frame, text = "Delete" ) self .delete_button.pack(side = tk.LEFT, padx = 5 ) # 分页按钮 self .pagination_frame = ttk.Frame( self .frame) self .pagination_frame.pack(pady = 10 ) self .prev_button = ttk.Button( self .pagination_frame, text = "Previous" ) self .prev_button.pack(side = tk.LEFT, padx = 5 ) self .page_label = ttk.Label( self .pagination_frame, text = "Page 1 of 1" ) self .page_label.pack(side = tk.LEFT, padx = 5 ) self .next_button = ttk.Button( self .pagination_frame, text = "Next" ) self .next_button.pack(side = tk.LEFT, padx = 5 ) def clear_tree( self ): """ :return: """ for item in self .tree.get_children(): self .tree.delete(item) def populate_tree( self , schools): """ :param schools: :return: """ for school in schools: self .tree.insert(' ', ' end', values = (school.school_id, school.school_name, school.school_tel_no)) def update_page_label( self , current_page, total_pages, tatol,pagesize): """ :param current_page: :param total_pages: :param tatol :param pagesize :return: """ self .page_label.config(text = f "Page {current_page} of {total_pages} {pagesize}/total:{tatol}" ) def open_add_window( self , save_callback): """ :param save_callback: :return: """ top = tk.Toplevel( self .frame) top.title( "Add School" ) top.iconbitmap( "favicon.ico" ) ttk.Label(top, text = "School ID:" ).grid(row = 0 , column = 0 , padx = 5 , pady = 5 ) id_entry = ttk.Entry(top) id_entry.grid(row = 0 , column = 1 , padx = 5 , pady = 5 ) ttk.Label(top, text = "School Name:" ).grid(row = 1 , column = 0 , padx = 5 , pady = 5 ) name_entry = ttk.Entry(top) name_entry.grid(row = 1 , column = 1 , padx = 5 , pady = 5 ) ttk.Label(top, text = "School Tel No:" ).grid(row = 2 , column = 0 , padx = 5 , pady = 5 ) tel_entry = ttk.Entry(top) tel_entry.grid(row = 2 , column = 1 , padx = 5 , pady = 5 ) def save_school(): """ :return: """ school_id = id_entry.get() school_name = name_entry.get() school_tel_no = tel_entry.get() if school_id and school_name and school_tel_no: save_callback(school_id, school_name, school_tel_no) top.destroy() ttk.Button(top, text = "Save" , command = save_school).grid(row = 3 , column = 0 , columnspan = 2 , pady = 10 ) def open_edit_window( self , school_id, school_name, school_tel_no, update_callback): """ :param school_id: :param school_name: :param school_tel_no: :param update_callback: :return: """ top = tk.Toplevel( self .frame) top.title( "Edit School" ) #top.iconbitmap("favicon.ico") ttk.Label(top, text = "School ID:" ).grid(row = 0 , column = 0 , padx = 5 , pady = 5 ) id_entry = ttk.Entry(top) id_entry.insert( 0 , school_id) id_entry.config(state = 'readonly' ) id_entry.grid(row = 0 , column = 1 , padx = 5 , pady = 5 ) ttk.Label(top, text = "School Name:" ).grid(row = 1 , column = 0 , padx = 5 , pady = 5 ) name_entry = ttk.Entry(top) name_entry.insert( 0 , school_name) name_entry.grid(row = 1 , column = 1 , padx = 5 , pady = 5 ) ttk.Label(top, text = "School Tel No:" ).grid(row = 2 , column = 0 , padx = 5 , pady = 5 ) tel_entry = ttk.Entry(top) tel_entry.insert( 0 , school_tel_no) tel_entry.grid(row = 2 , column = 1 , padx = 5 , pady = 5 ) def update_school(): """ :return: """ new_school_name = name_entry.get() new_school_tel_no = tel_entry.get() if new_school_name and new_school_tel_no: update_callback(school_id, new_school_name, new_school_tel_no) top.destroy() ttk.Button(top, text = "Update" , command = update_school).grid(row = 3 , column = 0 , columnspan = 2 , pady = 10 ) # encoding: utf-8 # 版权所有 2025 ©涂聚文有限公司 ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述: # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 3.11 # OS : Ubuntu 24.0 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 oracle 21c Neo4j # Datetime : 2025/2/20 20:47 # User : geovindu # Product : PyCharm # Project : pyMySqlDDDOrmDemo # File : presentation/controllers/school.py # explain : 学习 import tkinter as tk from application.services.school import SchoolService from domain.entities.school import School class SchoolController( object ): """ 表现层(Presentation Layer) 包含视图和控制器,处理用户界面和操作。 """ def __init__( self , service: SchoolService, view): """ :param service: :param view: """ self .service = service self .view = view self .current_page = 1 self .page_size = 10 self .search_query = "" self .total_pages = 1 self .view.search_button.config(command = self .search) self .view.add_button.config(command = self .add) self .view.edit_button.config(command = self .edit) self .view.delete_button.config(command = self .delete) self .view.prev_button.config(command = self .prev_page) self .view.next_button.config(command = self .next_page) self .load_data() def load_data( self ): """ :return: """ schools = self .service.get_schools( self .current_page, self .page_size, self .search_query) total_count = self .service.get_total_school_count( self .search_query) self .total_pages = (total_count + self .page_size - 1 ) / / self .page_size self .view.clear_tree() self .view.populate_tree(schools) self .view.update_page_label( self .current_page, self .total_pages,total_count, self .page_size) self .view.prev_button.config(state = tk.NORMAL if self .current_page > 1 else tk.DISABLED) self .view.next_button.config(state = tk.NORMAL if self .current_page < self .total_pages else tk.DISABLED) def search( self ): """ :return: """ self .search_query = self .view.search_entry.get() self .current_page = 1 self .load_data() def add( self ): """ :return: """ def save_callback(school_id, school_name, school_tel_no): new_school = School(school_id, school_name, school_tel_no) self .service.add_school(new_school) self .load_data() self .view.open_add_window(save_callback) def edit( self ): """ :return: """ selected_item = self .view.tree.selection() if selected_item: values = self .view.tree.item(selected_item, 'values' ) school_id, school_name, school_tel_no = values def update_callback(school_id, new_school_name, new_school_tel_no): updated_school = School(school_id, new_school_name, new_school_tel_no) self .service.update_school(updated_school) self .load_data() self .view.open_edit_window(school_id, school_name, school_tel_no, update_callback) def delete( self ): """ :return: """ selected_item = self .view.tree.selection() if selected_item: school_id = self .view.tree.item(selected_item, 'values' )[ 0 ] self .service.delete_school(school_id) self .load_data() def prev_page( self ): """ :return: """ if self .current_page > 1 : self .current_page - = 1 self .load_data() def next_page( self ): """ :return: """ if self .current_page < self .total_pages: self .current_page + = 1 self .load_data() |
调用:
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 | # encoding: utf-8 # 版权所有 2025 ©涂聚文有限公司 ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:先安装: python.exe -m pip install --upgrade pip # pip install pymysql # pip install sqlalchemy # sudo apt install python3-tk # pip install pillow # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 3.11 # OS : Ubuntu 24.0 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 oracle 21c Neo4j # Datetime : 2025/2/20 20:21 # User : geovindu # Product : PyCharm # Project : pyMySqlDDDOrmDemo # File : main.py # explain : 学习 ''' DDD 定义业务实体和存储库接口 domain --entities --repositories 基础设施层(Infrastructure) 实现存储库接口,与数据库交互。 infrastructure --database --model --repositories 应用层(Application) 封装业务逻辑。 application --services 表现层(Presentation) 包含视图和控制器,处理用户界面和操作。 presentation --views --controllers ''' import tkinter as tk from infrastructure.repositories import SchoolRepository,TeacherRepository # init 必须配置,才可以这样引用 from application.services import SchoolService, TeacherService from presentation.views import SchoolView, TeacherView from presentation.controllers import SchoolController, TeacherController if __name__ = = '__main__' : """ 主程序输出 """ root = tk.Tk() root.title( "学校老师管理系统" ) # 创建数据库存储库实例 school_repository = SchoolRepository() teacher_repository = TeacherRepository() # 创建服务实例 school_service = SchoolService(school_repository) teacher_service = TeacherService(teacher_repository) # 创建视图实例 school_view = SchoolView(root) teacher_view = TeacherView(root) school_view.frame.pack_forget() teacher_view.frame.pack_forget() # 创建控制器实例 school_controller = SchoolController(school_service, school_view) # 需要加上学校的务服实例。便于选择学校 teacher_controller = TeacherController(teacher_service, school_service, teacher_view) # 创建主菜单 menubar = tk.Menu(root) root.config(menu = menubar) # 创建主菜单下的子菜单 main_menu = tk.Menu(menubar, tearoff = 0 ) menubar.add_cascade(label = "管理菜单" , menu = main_menu) # 学校管理子菜单 school_menu = tk.Menu(main_menu, tearoff = 0 ) main_menu.add_cascade(label = "学校管理" , menu = school_menu) school_menu.add_command(label = "查看学校信息" , command = lambda : ( school_view.frame.pack(), teacher_view.frame.pack_forget() # 隐藏 )) # 老师管理子菜单 teacher_menu = tk.Menu(main_menu, tearoff = 0 ) main_menu.add_cascade(label = "老师管理" , menu = teacher_menu) teacher_menu.add_command(label = "查看老师信息" , command = lambda : ( teacher_view.frame.pack(), school_view.frame.pack_forget() # 隐藏 )) #root.iconbitmap(delattr="favicon.ico") #root.tk.call('wm', 'iconphoto', root._w, tk.PhotoImage(file='favicon.ico')) root.mainloop() print ( 'PyCharm,geovindu,Geovin Du,涂聚文!' ) |
输出:
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2023-02-21 CSharp: Select.Pdf Free Html To Pdf Converter for .NET
2014-02-21 sql and csharp: Split Function
2014-02-21 Colorbox - a jQuery lightbox
2012-02-21 csharp 在万年历中计算显示农历日子出错