python: login form

 

# 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, postgreSQL 17.0  oracle 21c Neo4j
# Datetime  : 2025/3/18 20:02
# User      : geovindu
# Product   : PyCharm
# Project   : pyMySqlDDDOrmDemo
# File      : user.py
# explain   : 学习
import tkinter as tk
from tkinter import messagebox
from tkinter import ttk
from tkinter import messagebox
from domain.entities.user import User
class LoginView(tk.Tk):
    """
    登录用户
    """
    def __init__(self):
        super().__init__()
        self.title("IT管理系统")
        window_width1 = 400
        window_height1 = 300
        self.iconbitmap("favicon.ico")
        self.resizable(False, False)
        self.maxsize(2000, 1000)
        self.minsize(window_width1, window_height1)
        x = (2000 - window_width1) // 2
        y = (1000 - window_height1) // 2
        self.geometry(f'{window_width1}x{window_height1}+{x}+{y}')

        tk.Label(self, text="用户名").grid(row=0, column=0, padx=5, pady=5)
        self.username_entry = tk.Entry(self)
        self.username_entry.grid(row=0, column=1, padx=5, pady=5)

        tk.Label(self, text="密码").grid(row=1, column=0, padx=5, pady=5)
        self.password_entry = tk.Entry(self, show="*")
        self.password_entry.grid(row=1, column=1, padx=5, pady=5)
        self.login_button = tk.Button(self, text='   登入   ', command=self.on_login_click)
        self.login_button.grid(row=2, column=1, padx=5, pady=5)

    def on_login_click(self):
        username = self.username_entry.get()
        password = self.password_entry.get()
        self.notify_login_attempt(username, password)

    def set_login_result(self, success, message):
        if success:
            messagebox.showinfo("Success!", message)
            self.destroy()
        else:
            messagebox.showerror("Error!", message)

    def notify_login_attempt(self, username, password):
        pass



# 视图层
class UserView(object):
    """
    用户管理
    """
    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_var = tk.StringVar()
        self.search_entry = ttk.Entry(self.search_frame, textvariable=self.search_var)
        self.search_entry.pack(side=tk.LEFT,pady=10)
        self.search_button = ttk.Button(self.search_frame, text="搜索")
        self.search_button.pack(side=tk.LEFT,pady=5)

        # Treeview
        self.tree = ttk.Treeview(self.frame, columns=('Id', 'UserName', 'Password', 'email'), show='headings')
        self.tree.heading('Id', text='ID')
        self.tree.heading('UserName', text='用户名')
        self.tree.heading('Password', text='密码')
        self.tree.heading('email', text='邮箱')
        self.tree.pack(pady=20)
        self.tree.bind("<Double-1>", self.on_double_click)

        # 分页按钮
        self.pagination_frame = ttk.Frame(self.frame)
        self.pagination_frame.pack(pady=10)
        self.button_frame = ttk.Frame(self.pagination_frame)
        self.button_frame.pack(pady=10)
        self.prev_button = ttk.Button(self.pagination_frame, text="上一页")
        self.prev_button.pack(side=tk.LEFT, padx=10)
        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="下一页")
        self.next_button.pack(side=tk.LEFT, padx=10)

        self.button_frame = ttk.Frame(self.frame)
        self.button_frame.pack(pady=10)
        # 添加按钮
        self.add_button = ttk.Button(self.button_frame, text="添加")
        self.add_button.pack(side=tk.RIGHT, padx=10)
        self.edit_button = ttk.Button(self.button_frame, text="编辑")
        self.edit_button.pack(side=tk.LEFT, padx=5)
        # 删除按钮
        self.delete_button = ttk.Button(self.button_frame, text="删除")
        self.delete_button.pack(side=tk.RIGHT, padx=10)

        self.presenter = None




    def clear_tree(self):
        """

        :return:
        """
        for item in self.tree.get_children():
            self.tree.delete(item)

    def populate_tree(self, users):
        """

        :param users:
        :return:
        """
        for user in users:
            print(user)
            print(user.username)
            self.tree.insert('', 'end', values=(user.id,user.username, user.email,user.password))

    def update_page_label(self, current_page, total_pages,total,pagesize):
        """

        :param current_page:
        :param total_pages:
        :param total:
        :param pagesize
        :return:
        """
        self.page_label.config(text=f"第 {current_page} 页/ 共 {total_pages} 页 每页{pagesize}条/共{total} 条记录")

    def show_add_window(self,schoolmap, save_callback):
        top = tk.Toplevel(self.frame)
        top.title("添加用户")
        # top.iconbitmap("favicon.ico")

        # 用户名
        ttk.Label(top, text="用户名:").grid(row=0, column=0, padx=10, pady=5)
        username_entry = ttk.Entry(top)
        username_entry.grid(row=0, column=1, padx=10, pady=5)

        # 密码
        ttk.Label(top, text="密码:").grid(row=1, column=0, padx=10, pady=5)
        password_entry = ttk.Entry(top)
        password_entry.grid(row=1, column=1, padx=10, pady=5)

        # 邮箱
        ttk.Label(top, text="邮箱:").grid(row=2, column=0, padx=10, pady=5)
        email_entry = ttk.Entry(top)
        email_entry.grid(row=2, column=1, padx=10, pady=5)

        def save_user():
            username = username_entry.get()
            password = password_entry.get()
            email = email_entry.get()
            if username and password and email:
                if all([username, password, email]):
                    save_callback(username, password, email)
                    top.destroy()
            else:
                messagebox.showerror("错误", "用户名、密码和邮箱不能为空")

        # 保存按钮
        ttk.Button(top, text="保存", command=save_user).grid(row=3, column=0, columnspan=2, pady=10)

    def open_edit_window(self, user_map, user_id, username, password, email, update_callback):
        if user_id:
            top = tk.Toplevel(self.frame)
            top.title("编辑用户")
            # top.iconbitmap("favicon.ico")

            # 用户名
            ttk.Label(top, text="用户名:").grid(row=0, column=0, padx=10, pady=5)
            top.username_entry = ttk.Entry(top)
            top.username_entry.insert(0, username)
            top.username_entry.grid(row=0, column=1, padx=10, pady=5)

            # 密码
            ttk.Label(top, text="密码:").grid(row=1, column=0, padx=10, pady=5)
            top.password_entry = ttk.Entry(top)
            top.password_entry.insert(0, password)
            top.password_entry.grid(row=1, column=1, padx=10, pady=5)

            # 邮箱
            ttk.Label(top, text="邮箱:").grid(row=2, column=0, padx=10, pady=5)
            top.email_entry = ttk.Entry(top)
            top.email_entry.insert(0, email)
            top.email_entry.grid(row=2, column=1, padx=10, pady=5)

            def update_user():
                username = top.username_entry.get()
                password = top.password_entry.get()
                email = top.email_entry.get()
                if username and password and email:
                    update_callback(user_id, username, password, email)
                    top.destroy()
                else:
                    messagebox.showerror("错误", "用户名、密码和邮箱不能为空")

            # 保存按钮
            ttk.Button(top, text="保存", command=update_user).grid(row=3, column=0, columnspan=2, pady=10)

    def on_double_click(self, event):
        selected_item = self.tree.selection()
        if selected_item:
            values = self.tree.item(selected_item, 'values')
            user_id, username, password, email = values
            # 检查 presenter 是否已经正确初始化
            if self.presenter:
                self.presenter.edit(user_id, username, password, email)
            else:
                print("Presenter 未初始化")

  

# 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, postgreSQL 17.0  oracle 21c Neo4j
# Datetime  : 2025/3/18 20:02
# User      : geovindu
# Product   : PyCharm
# Project   : pyMySqlDDDOrmDemo
# File      : user.py
# explain   : 学习

from presentation.views.user import LoginView
from application.services.user import UserService
from domain.entities.user import User

import tkinter as tk
from infrastructure.repositories import SchoolRepository,TeacherRepository    # init 必须配置,才可以这样引用
# from infrastructure.repositories import *
from application.services import SchoolService, TeacherService
# from application.services import *
from presentation.views import SchoolView, TeacherView
# from presentation.views import *
from presentation.controllers import SchoolController, TeacherController
# from presentation.controllers import *

from infrastructure.repositories.user import UserRepository
from presentation.views.user import UserView
from application.services.user import UserService



class UserController:
    """
    登录窗口
    """
    def __init__(self, view: LoginView, user_repository: UserService):
        """

        :param view:
        :param user_repository:
        """
        self.view = view
        self.user_repository = user_repository
        self.view.notify_login_attempt = self.handle_login_attempt



    def handle_login_attempt(self, username, password):
        """

        :param username:
        :param password:
        :return:
        """
        if not username or not password:
            self.view.set_login_result(False, "账号密码不可为空")
            return

        user = self.user_repository.get_user_by_username(username)
        if user is None or user.password != password:
            self.view.set_login_result(False, "账号密码错误")
        else:
            self.view.set_login_result(True, "欢迎登入管理系统")

            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()

            user_repository = UserRepository()
            userserver=UserService(user_repository)

            userview = UserView(root)
            userview.frame.pack_forget()

            #presenter = UserPresenter(userserver,userview)


            # 创建控制器实例
            school_controller = SchoolController(school_service, school_view)
            # 需要加上学校的务服实例。便于选择学校
            teacher_controller = TeacherController(teacher_service, school_service, teacher_view)

            user_controller = UserPresenter(userserver, userview)



            # 创建主菜单
            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(),  # 隐藏
                userview.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(),  # 隐藏
                userview.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_forget(),
                school_view.frame.pack_forget(),  # 隐藏
                userview.frame.pack()
            ))

            root.iconbitmap("favicon.ico")
            root.mainloop()


# 呈现器层
class UserPresenter:
    """
    用户管理
    """
    def __init__(self, service: UserService, view):
        self.service = service
        self.view = view
        self.current_page = 1
        self.page_size = 10
        self.search_query = ""
        self.total_pages = 1
        self.total_count = 0
        self.user_map = None
        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.edit_button.config(command=lambda: self.edit(None, None, None, None))
        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.view.tree.on_double_click(command=self.editclick)
        self.view.presenter = self

        self.load_data()



    def load_data(self):
        """

        :return:
        """
        users = self.service.get_all_users(self.current_page, self.page_size, self.search_query)
        print(users)
        self.total_count = self.service.get_total_pages(self.search_query)

        self.total_pages = (self.total_count + self.page_size - 1) // self.page_size

        self.view.clear_tree()
        self.view.populate_tree(users)

        print(self.current_page,self.total_count, self.total_pages)

        self.view.update_page_label(self.current_page, self.total_pages, self.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)

        # 选择
        usersd = self.service.get_all()
        # 这个有错语
        self.user_map = {s.username: s.id for s in usersd}


    def search(self):
        """

        :return:
        """
        self.search_query = self.view.search_entry.get()
        self.current_page = 1
        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()

    def add(self):
        """

        :return:
        """

        def save_callback(username, password, email):
            """

            :param teacher_id:
            :param first_name:
            :param last_name:
            :param gender:
            :param tel_no:
            :param school_id:
            :return:
            """

            new_user = User(username, password, email)
            self.service.add_user(username, password, email)
            self.load_data()

        # 打开添加窗口
        self.view.show_add_window(self.user_map, save_callback)

    def edit(self, user_id, username, password, email):
        if not user_id:
            selected_item = self.view.tree.selection()
            if selected_item:
                values = self.view.tree.item(selected_item, 'values')
                user_id, username, password, email = values

        if user_id:
            def update_callback(user_id, username, password, email):
                updated_user = User(user_id, username, password, email)
                self.service.update_user(user_id, username, password, email)
                self.load_data()

            self.view.open_edit_window(self.user_map, user_id, username, password, email, update_callback)


    def delete(self):
        """

        :return:
        """
        selected_item = self.view.tree.selection()
        if selected_item:
            user_id = self.view.tree.item(selected_item, 'values')[0]
            self.service.delete_user(user_id)
            self.load_data()

  

posted @ 2025-03-21 22:20  ®Geovin Du Dream Park™  阅读(22)  评论(0)    收藏  举报