当前位置: 首页 > news >正文

python: DDD+ORM+pyQt6 using MySql

sql:

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`)   #主鍵
)ENGINE=MyISAM 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`),   #主鍵
     CONSTRAINT TeacherSchool_ibfk_1 FOREIGN KEY(TeacherSchoolId) REFERENCES School(SchoolId)  #外鍵
)ENGINE=MyISAM COMMENT='老師表Teacher Table' DEFAULT CHARSET=utf8; 

数据处理各层,就用前面的文章提到的就可以了。只是呈现器(MVP)改成pyQt6就可以了。

项目结构:

# 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/29 22:51
# User      : geovindu
# Product   : PyCharm
# Project   : pymysqlDDDQt
# File      : school.py
# explain   : 学习
import sys
from PyQt6.QtWidgets import QApplication, QTabWidget
from presentation.controllers.school import SchoolController
from presentation.views.school import SchoolView


class SchoolPresenter:
    """

    """
    def __init__(self, view, controller: SchoolController):
        """

        :param view:
        :param controller:
        """
        self.view = view
        self.controller = controller
        self.current_page = 1
        self.page_size = 10
        self.search_query = ""
        self.setup_connections()
        self.update_table()

    def setup_connections(self):
        """

        :return:
        """
        self.view.search_button.clicked.connect(self.on_search)
        self.view.add_button.clicked.connect(self.on_add)
        self.view.edit_button.clicked.connect(self.on_edit)
        self.view.delete_button.clicked.connect(self.on_delete)
        self.view.prev_button.clicked.connect(self.on_prev_page)
        self.view.next_button.clicked.connect(self.on_next_page)

    def update_table(self):
        """

        :return:
        """
        try:
            schools = self.controller.get_all_schools(
                self.current_page, self.page_size, self.search_query)
            print(schools)
            self.view.set_table_data(schools)
            total_records = self.controller.get_total_schools(self.search_query)
            print(total_records)
            total_pages = (total_records + self.page_size - 1) // self.page_size
            self.view.set_pagination_info(self.current_page, total_pages, total_records)
        except Exception as e:
            print(f"更新学校表格数据时出错: {e}")

    def on_search(self):
        """

        :return:
        """
        self.search_query = self.view.get_search_query()
        self.current_page = 1
        self.update_table()

    def on_add(self):
        """

        :return:
        """
        try:
            school = self.view.show_add_dialog()
            if school:
                self.controller.add_school(school)
                self.update_table()
                self.view.show_message("School added successfully.")
        except Exception as e:
            print(f"添加学校时出错: {e}")

    def on_edit(self):
        """

        :return:
        """
        try:
            row = self.view.get_selected_row()
            if row != -1:
                school_id = self.view.table.item(row, 0).text()
                school = self.controller.get_all_schools(
                    self.current_page, self.page_size, self.search_query)[row]
                edited_school = self.view.show_edit_dialog(school)
                if edited_school:
                    edited_school.SchoolId = school_id
                    self.controller.update_school(edited_school)
                    self.update_table()
                    self.view.show_message("School updated successfully.")
            else:
                self.view.show_message("Please select a school to edit.")
        except Exception as e:
            print(f"编辑学校时出错: {e}")

    def on_delete(self):
        """

        :return:
        """
        try:
            row = self.view.get_selected_row()
            if row != -1:
                school_id = self.view.table.item(row, 0).text()
                self.controller.delete_school(school_id)
                self.update_table()
                self.view.show_message("School deleted successfully.")
            else:
                self.view.show_message("Please select a school to delete.")
        except Exception as e:
            print(f"删除学校时出错: {e}")

    def on_prev_page(self):
        """

        :return:
        """
        if self.current_page > 1:
            self.current_page -= 1
            self.update_table()

    def on_next_page(self):
        """

        :return:
        """
        total_schools = self.controller.get_total_schools(self.search_query)
        total_pages = (total_schools + self.page_size - 1) // self.page_size
        if self.current_page < total_pages:
            self.current_page += 1
            self.update_table()



# 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/29 22:51
# User      : geovindu
# Product   : PyCharm
# Project   : pymysqlDDDQt
# File      : teacher.py
# explain   : 学习
from presentation.controllers.teacher import TeacherController
from presentation.views.teacher import TeacherView
from presentation.controllers.school import SchoolController


class TeacherPresenter:
    """
    
    """
    def __init__(self, view, controller:TeacherController,scontroller: SchoolController):
        self.view = view
        self.controller = controller
        self.scontroller = scontroller
        self.school_map = None
        self.current_page = 1
        self.page_size = 10
        self.search_query = ""
        self.setup_connections()
        self.update_table()

    def setup_connections(self):
        """
        
        :return: 
        """
        self.view.search_button.clicked.connect(self.on_search)
        self.view.add_button.clicked.connect(self.on_add)
        self.view.edit_button.clicked.connect(self.on_edit)
        self.view.delete_button.clicked.connect(self.on_delete)
        self.view.prev_button.clicked.connect(self.on_prev_page)
        self.view.next_button.clicked.connect(self.on_next_page)
        # 学校选择
        schools = self.scontroller.get_schoolall()
        print("schools:")
        print(schools)
        # 这个有错语
        self.school_map = schools   # {s.school_name: s.school_id for s in schools}
    def update_table(self):
        """
        
        :return: 
        """
        try:
            teachers = self.controller.get_all_teachers(
                self.current_page, self.page_size, self.search_query)
            self.view.set_table_data(teachers)
            total_records = self.controller.get_total_teachers(self.search_query)
            total_pages = (total_records + self.page_size - 1) // self.page_size
            self.view.set_pagination_info(self.current_page, total_pages, total_records)

        except Exception as e:
            print(f"更新教师表格数据时出错: {e}")

    def on_search(self):
        """
        
        :return: 
        """
        self.search_query = self.view.get_search_query()
        self.current_page = 1
        self.update_table()

    def on_add(self):
        """
        
        :return: 
        """
        try:
            teacher = self.view.show_add_dialog(self.school_map)
            if teacher:
                self.controller.add_teacher(teacher)
                self.update_table()
                self.view.show_message("Teacher added successfully.")
        except Exception as e:
            print(f"添加教师时出错: {e}")

    def on_edit(self):
        """
        
        :return: 
        """
        try:
            row = self.view.get_selected_row()
            if row != -1:
                teacher_id = self.view.table.item(row, 0).text()
                teacher = self.controller.get_all_teachers(
                    self.current_page, self.page_size, self.search_query)[row]
                #
                edited_teacher = self.view.show_edit_dialog(teacher,self.school_map)
                if edited_teacher:
                    edited_teacher.TeacherId = teacher_id
                    self.controller.update_teacher(edited_teacher)
                    self.update_table()
                    self.view.show_message("Teacher updated successfully.")
            else:
                self.view.show_message("Please select a teacher to edit.")
        except Exception as e:
            print(f"编辑教师时出错: {e}")

    def on_delete(self):
        """
        
        :return: 
        """
        try:
            row = self.view.get_selected_row()
            if row != -1:
                teacher_id = self.view.table.item(row, 0).text()
                self.controller.delete_teacher(teacher_id)
                self.update_table()
                self.view.show_message("Teacher deleted successfully.")
            else:
                self.view.show_message("Please select a teacher to delete.")
        except Exception as e:
            print(f"删除教师时出错: {e}")

    def on_prev_page(self):
        """
        
        :return: 
        """
        if self.current_page > 1:
            self.current_page -= 1
            self.update_table()

    def on_next_page(self):
        """
        
        :return: 
        """
        total_teachers = self.controller.get_total_teachers(self.search_query)
        total_pages = (total_teachers + self.page_size - 1) // self.page_size
        if self.current_page < total_pages:
            self.current_page += 1
            self.update_table()


# 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/29 21:34
# User      : geovindu
# Product   : PyCharm
# Project   : pymysqlDDDQt
# File      : school.py
# explain   : 学习
from PyQt6.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QTableWidget, QTableWidgetItem,
    QPushButton, QLabel, QLineEdit, QDialog, QFormLayout, QDialogButtonBox, QMessageBox, QMdiArea, QMdiSubWindow
)
from domain.entities.school import School


class SchoolView(QWidget):
    """

    """
    def __init__(self):
        """

        """
        super().__init__()
        self.initUI()

    def initUI(self):
        """

        :return:
        """
        self.mdi_area = QMdiArea()
        self.sub_window = QMdiSubWindow()
        self.main_widget = QWidget()

        self.table = QTableWidget()
        self.table.setColumnCount(3)
        self.table.setHorizontalHeaderLabels(
            ['SchoolId', 'SchoolName', 'SchoolTelNo'])

        self.search_input = QLineEdit()
        self.search_button = QPushButton("Search")
        self.add_button = QPushButton("Add")
        self.edit_button = QPushButton("Edit")
        self.delete_button = QPushButton("Delete")
        self.prev_button = QPushButton("Prev")
        self.next_button = QPushButton("Next")

        self.pagination_label = QLabel()

        search_layout = QHBoxLayout()
        search_layout.addWidget(self.search_input)
        search_layout.addWidget(self.search_button)

        button_layout = QHBoxLayout()
        button_layout.addWidget(self.add_button)
        button_layout.addWidget(self.edit_button)
        button_layout.addWidget(self.delete_button)
        button_layout.addWidget(self.prev_button)
        button_layout.addWidget(self.next_button)
        button_layout.addWidget(self.pagination_label)

        layout = QVBoxLayout()
        layout.addLayout(search_layout)
        layout.addWidget(self.table)
        layout.addLayout(button_layout)

        self.main_widget.setLayout(layout)
        self.sub_window.setWidget(self.main_widget)
        self.mdi_area.addSubWindow(self.sub_window)

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.mdi_area)
        self.setLayout(main_layout)

    def set_table_data(self, schools):
        """

        :param schools:
        :return:
        """
        self.table.setRowCount(len(schools))

        for row, school in enumerate(schools):
            self.table.setItem(row, 0, QTableWidgetItem(school.school_id))
            self.table.setItem(row, 1, QTableWidgetItem(school.school_name))
            self.table.setItem(row, 2, QTableWidgetItem(school.school_tel_no))

    def get_selected_row(self):
        """

        :return:
        """
        selected_items = self.table.selectedItems()
        if selected_items:
            return selected_items[0].row()
        return -1

    def get_search_query(self):
        """

        :return:
        """
        return self.search_input.text()

    def show_add_dialog(self):
        """

        :return:
        """
        dialog = QDialog(self)
        dialog.setWindowTitle("Add School")
        layout = QFormLayout()

        id_input = QLineEdit()
        name_input = QLineEdit()
        tel_input = QLineEdit()

        layout.addRow("School ID:", id_input)
        layout.addRow("School Name:", name_input)
        layout.addRow("School Tel No:", tel_input)

        button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
        button_box.accepted.connect(dialog.accept)
        button_box.rejected.connect(dialog.reject)
        layout.addWidget(button_box)

        dialog.setLayout(layout)

        if dialog.exec() == QDialog.DialogCode.Accepted:
            school_id = id_input.text()
            name = name_input.text()
            tel_no = tel_input.text()
            return School(SchoolId=school_id, SchoolName=name, SchoolTelNo=tel_no)
        return None

    def show_edit_dialog(self, school):
        """

        :param school:
        :return:
        """
        dialog = QDialog(self)
        dialog.setWindowTitle("Edit School")
        layout = QFormLayout()

        id_input = QLineEdit(school.school_id)
        name_input = QLineEdit(school.school_name)
        tel_input = QLineEdit(school.school_tel_no)

        layout.addRow("School ID:", id_input)
        layout.addRow("School Name:", name_input)
        layout.addRow("School Tel No:", tel_input)

        button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
        button_box.accepted.connect(dialog.accept)
        button_box.rejected.connect(dialog.reject)
        layout.addWidget(button_box)

        dialog.setLayout(layout)

        if dialog.exec() == QDialog.DialogCode.Accepted:
            school.SchoolId = id_input.text()
            school.SchoolName = name_input.text()
            school.SchoolTelNo = tel_input.text()
            return school
        return None

    def show_message(self, message):
        """

        :param message:
        :return:
        """
        QMessageBox.information(self, 'Message', message)

    def set_pagination_info(self, current_page, total_pages, total_records):
        """

        :param current_page:
        :param total_pages:
        :param total_records:
        :return:
        """
        info_text = f"当前页: {current_page} / 总页数: {total_pages}  总记录数: {total_records}"
        self.pagination_label.setText(info_text)


# 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/29 21:34
# User      : geovindu
# Product   : PyCharm
# Project   : pymysqlDDDQt
# File      : teacher.py
# explain   : 学习

from PyQt6.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QTableWidget, QTableWidgetItem,
    QPushButton, QLabel, QLineEdit, QDialog, QFormLayout, QDialogButtonBox, QMessageBox, QMdiArea, QMdiSubWindow, QComboBox
)
from domain.entities.teacher import Teacher


class TeacherView(QWidget):
    """

    """
    def __init__(self):
        """

        """
        super().__init__()
        self.initUI()

    def initUI(self):
        """

        :return:
        """
        self.mdi_area = QMdiArea()
        self.sub_window = QMdiSubWindow()
        self.main_widget = QWidget()

        self.table = QTableWidget()
        self.table.setColumnCount(6)
        self.table.setHorizontalHeaderLabels([
            'TeacherId', 'TeacherFirstName', 'TeacherLastName',
            'TeacherGender', 'TeacherTelNo', 'TeacherSchoolId'
        ])

        self.search_input = QLineEdit()
        self.search_button = QPushButton("Search")
        self.add_button = QPushButton("Add")
        self.edit_button = QPushButton("Edit")
        self.delete_button = QPushButton("Delete")
        self.prev_button = QPushButton("Prev")
        self.next_button = QPushButton("Next")

        self.pagination_label = QLabel()

        search_layout = QHBoxLayout()
        search_layout.addWidget(self.search_input)
        search_layout.addWidget(self.search_button)

        button_layout = QHBoxLayout()
        button_layout.addWidget(self.add_button)
        button_layout.addWidget(self.edit_button)
        button_layout.addWidget(self.delete_button)
        button_layout.addWidget(self.prev_button)
        button_layout.addWidget(self.next_button)
        button_layout.addWidget(self.pagination_label)

        layout = QVBoxLayout()
        layout.addLayout(search_layout)
        layout.addWidget(self.table)
        layout.addLayout(button_layout)

        self.main_widget.setLayout(layout)
        self.sub_window.setWidget(self.main_widget)
        self.mdi_area.addSubWindow(self.sub_window)

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.mdi_area)
        self.setLayout(main_layout)

    def set_table_data(self, teachers):
        """

        :param teachers:
        :return:
        """
        self.table.setRowCount(len(teachers))
        for row, teacher in enumerate(teachers):
            self.table.setItem(row, 0, QTableWidgetItem(teacher.teacher_id))
            self.table.setItem(row, 1, QTableWidgetItem(
                teacher.first_name))
            self.table.setItem(row, 2, QTableWidgetItem(
                teacher.last_name))
            self.table.setItem(row, 3, QTableWidgetItem(teacher.gender))
            self.table.setItem(row, 4, QTableWidgetItem(teacher.tel_no))
            self.table.setItem(row, 5, QTableWidgetItem(
                teacher.school_id))

    def get_selected_row(self):
        """

        :return:
        """
        selected_items = self.table.selectedItems()
        if selected_items:
            return selected_items[0].row()
        return -1

    def get_search_query(self):
        """

        :return:
        """
        return self.search_input.text()

    def show_add_dialog(self,school_map):
        """

        :param school_map:
        :return:
        """
        dialog = QDialog(self)
        dialog.setWindowTitle("Add Teacher")
        layout = QFormLayout()

        id_input = QLineEdit()
        first_name_input = QLineEdit()
        last_name_input = QLineEdit()
        gender_input = QLineEdit()
        tel_input = QLineEdit()
        school_combo = QComboBox()

        # 获取所有学校信息
        schools =school_map # self.school_service.get_schoolall()
        print("获取所有学校信息")
        print(schools)
        for school in school_map:
            school_combo.addItem(f"{school.school_id} - {school.school_name}", school.school_id)

        layout.addRow("Teacher ID:", id_input)
        layout.addRow("First Name:", first_name_input)
        layout.addRow("Last Name:", last_name_input)
        layout.addRow("Gender:", gender_input)
        layout.addRow("Tel No:", tel_input)
        layout.addRow("School:", school_combo)

        button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
        button_box.accepted.connect(dialog.accept)
        button_box.rejected.connect(dialog.reject)
        layout.addWidget(button_box)

        dialog.setLayout(layout)

        if dialog.exec() == QDialog.DialogCode.Accepted:
            teacher_id = id_input.text()
            first_name = first_name_input.text()
            last_name = last_name_input.text()
            gender = gender_input.text()
            tel_no = tel_input.text()
            school_id = school_combo.currentData()

            return Teacher(TeacherId=teacher_id, TeacherFirstName=first_name,
                           TeacherLastName=last_name, TeacherGender=gender,
                           TeacherTelNo=tel_no, TeacherSchoolId=school_id)
        return None

    def show_edit_dialog(self, teacher,school_map):
        """

        :param teacher:
        :param school_map:
        :return:
        """
        dialog = QDialog(self)
        dialog.setWindowTitle("Edit Teacher")
        layout = QFormLayout()

        id_input = QLineEdit(teacher.teacher_id)
        first_name_input = QLineEdit(teacher.first_name)
        last_name_input = QLineEdit(teacher.last_name)
        gender_input = QLineEdit(teacher.gender)
        tel_input = QLineEdit(teacher.tel_no)
        school_combo = QComboBox()

        # 获取所有学校信息
        schools = school_map  # self.school_service.get_schoolall()
        for school in schools:
            school_combo.addItem(f"{school.school_id} - {school.school_name}", school.school_id)
            if school.school_id == teacher.school_id:
                school_combo.setCurrentIndex(school_combo.count() - 1)

        layout.addRow("Teacher ID:", id_input)
        layout.addRow("First Name:", first_name_input)
        layout.addRow("Last Name:", last_name_input)
        layout.addRow("Gender:", gender_input)
        layout.addRow("Tel No:", tel_input)
        layout.addRow("School:", school_combo)

        button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
        button_box.accepted.connect(dialog.accept)
        button_box.rejected.connect(dialog.reject)
        layout.addWidget(button_box)

        dialog.setLayout(layout)

        if dialog.exec() == QDialog.DialogCode.Accepted:
            teacher.TeacherId = id_input.text()
            teacher.TeacherFirstName = first_name_input.text()
            teacher.TeacherLastName = last_name_input.text()
            teacher.TeacherGender = gender_input.text()
            teacher.TeacherTelNo = tel_input.text()
            teacher.TeacherSchoolId = school_combo.currentData()
            return teacher
        return None

    def show_message(self, message):
        """

        :param message:
        :return:
        """
        QMessageBox.information(self, 'Message', message)

    def set_pagination_info(self, current_page, total_pages, total_records):
        """

        :param current_page:
        :param total_pages:
        :param total_records:
        :return:
        """
        info_text = f"当前页: {current_page} / 总页数: {total_pages}  总记录数: {total_records}"
        self.pagination_label.setText(info_text)

输出:

加上登录进入主窗口

# 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/30 13:12
# User      : geovindu
# Product   : PyCharm
# Project   : pymysqlDDDQt
# File      : login.py
# explain   : 学习


import sys
from PyQt6.QtWidgets import QApplication, QTabWidget, QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton, QMessageBox,QMenuBar, QMenu, QMainWindow,QStackedWidget
from PyQt6.QtGui import QIcon
from PyQt6.QtGui import QAction
from PyQt6.QtSql import QSqlDatabase, QSqlQuery




''' 
# 1 ok

class MainWindow(QWidget):
    """
    # 假设其他导入和控制器/视图类已正确实现
    """

    def __init__(self):
        super().__init__()
        self.presenters = {}  # 使用字典持久保存Presenter
        self.initUI()

    def initUI(self):
        self.tab_widget = QTabWidget(self)

        # 学校视图
        self.school_view = SchoolView()
        school_controller = SchoolController()
        SchoolPresenter(self.school_view, school_controller)
        self.presenters['school'] = SchoolPresenter  # 保持强引用
        self.tab_widget.addTab(self.school_view, "学校管理")

        # 教师视图
        self.teacher_view = TeacherView()
        teacher_controller = TeacherController()
        TeacherPresenter(self.teacher_view, teacher_controller, school_controller)
        self.presenters['teacher'] = TeacherPresenter  # 保持强引用
        self.tab_widget.addTab(self.teacher_view, "教师管理")

        # 用户视图
        self.user_view = UserView()
        user_controller = UserController()
        UserPresenter(self.user_view, user_controller)
        self.presenters['user'] = UserPresenter  # 保持强引用
        self.tab_widget.addTab(self.user_view, "用户管理")

        layout = QVBoxLayout(self)
        layout.addWidget(self.tab_widget)
        self.setLayout(layout)
        self.setWindowTitle("主管理界面")
        self.resize(800, 600)


class LoginWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        layout = QVBoxLayout()

        self.username_label = QLabel("用户名:")
        self.username_input = QLineEdit()
        self.password_label = QLabel("密码:")
        self.password_input = QLineEdit()
        self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
        self.login_button = QPushButton("登录")
        self.login_button.clicked.connect(self.login)

        layout.addWidget(self.username_label)
        layout.addWidget(self.username_input)
        layout.addWidget(self.password_label)
        layout.addWidget(self.password_input)
        layout.addWidget(self.login_button)

        self.setLayout(layout)
        self.setWindowTitle("登录")
        self.setFixedSize(300, 200)

    def login(self):
        username = self.username_input.text()
        password = self.password_input.text()

        ubll = UserController()
        user = ubll.get_user_by_username(username)

        if user and user.password == password:
            self.main_window = MainWindow()  # 创建主窗口实例
            self.main_window.show()  # 显示主窗口
            self.close()  # 关闭登录窗口
        else:
            QMessageBox.warning(self, "登录失败", "用户名或密码错误")


if __name__ == '__main__':
    try:
        app = QApplication(sys.argv)
        app.setWindowIcon(QIcon('./favicon.ico'))

        login_window = LoginWindow()
        login_window.show()
        sys.exit(app.exec())

    except Exception as e:
        QMessageBox.critical(None, "启动错误", f"应用程序启动失败: {str(e)}")
        sys.exit(1)            

'''

'''    2   ok  tab 考虑事件无效问题

class LoginWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        # self.db = self.connect_to_database()
        self.tab_widget = None

    def initUI(self):
        layout = QVBoxLayout()

        self.username_label = QLabel("用户名:")
        self.username_input = QLineEdit()
        self.password_label = QLabel("密码:")
        self.password_input = QLineEdit()
        self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
        self.login_button = QPushButton("登录")
        self.login_button.clicked.connect(self.login)

        layout.addWidget(self.username_label)
        layout.addWidget(self.username_input)
        layout.addWidget(self.password_label)
        layout.addWidget(self.password_input)
        layout.addWidget(self.login_button)

        self.setLayout(layout)
        self.setWindowTitle("登录")

    def login(self):
        username = self.username_input.text()
        password = self.password_input.text()
        print('login')

        ubll = UserController()
        user = ubll.get_user_by_username(username)
        print("user:", user)
        if user is None or user.password != password:
            QMessageBox.warning(self, "登录失败", "用户名或密码错误,请重试。")
        else:
            QMessageBox.information(self, "登录成功", "欢迎登录!")
            self.show_main_window()
            self.close()


    def show_main_window(self):
        try:
            # 不设置父窗口
            self.tab_widget = QTabWidget()

            school_view = SchoolView()
            school_controller = SchoolController()
            school_presenter = SchoolPresenter(school_view, school_controller)            
            self.tab_widget.addTab(school_view, "Schools")

            teacher_view = TeacherView()
            teacher_controller = TeacherController()
            teacher_presenter = TeacherPresenter(teacher_view, teacher_controller, school_controller)            
            self.tab_widget.addTab(teacher_view, "Teachers")

            user_view = UserView()
            user_controller = UserController()
            user_presenter = UserPresenter(user_view, user_controller)
            #self.presenters['uers'] = user_presenter  # 保持强引用
            self.tab_widget.addTab(user_view, "Users")

            self.tab_widget.show()
        except Exception as e:
            QMessageBox.critical(self, "主窗体显示错误", f"显示主窗体时出现错误: {str(e)}")


if __name__ == '__main__':
    try:
        app = QApplication(sys.argv)
        app.setWindowIcon(QIcon('./favicon.ico'))
        login_window = LoginWindow()
        login_window.show()
        sys.exit(app.exec())
    except Exception as e:
        print(f"启动应用程序时出错: {e}")
'''


# 3 菜单式的 ok

class LoginWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.school_view = None
        self.teacher_view = None
        self.user_view = None
        self.school_presenter = None
        self.teacher_presenter = None
        self.user_presenter = None
        self.main_window = None  # 新增类属性

    def initUI(self):
        layout = QVBoxLayout()

        self.username_label = QLabel("用户名:")
        self.username_input = QLineEdit()
        self.password_label = QLabel("密码:")
        self.password_input = QLineEdit()
        self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
        self.login_button = QPushButton("登录")
        self.login_button.clicked.connect(self.login)

        layout.addWidget(self.username_label)
        layout.addWidget(self.username_input)
        layout.addWidget(self.password_label)
        layout.addWidget(self.password_input)
        layout.addWidget(self.login_button)

        self.setLayout(layout)
        self.setWindowTitle("登录")

    def login(self):
        username = self.username_input.text()
        password = self.password_input.text()
        from presentation.controllers.user import UserController
        ubll = UserController()
        user = ubll.get_user_by_username(username)
        print("user:", user)
        if user is None or user.password != password:
            QMessageBox.warning(self, "登录失败", "用户名或密码错误,请重试。")
        else:
            QMessageBox.information(self, "登录成功", "欢迎登录!")
            self.show_main_window()
            self.close()

    def show_main_window(self):
        try:
            # 正确创建主窗口并保持引用
            self.main_window = QMainWindow()  # 不再需要 QApplication.instance()
            self.main_window.setWindowTitle("Main Window")

            # 创建菜单栏 (关键修改1:直接使用 main_window 的方法创建)
            menu_bar = self.main_window.menuBar()  # 这是正确获取 QMainWindow 菜单栏的方法

            # 创建菜单项
            main_menu = menu_bar.addMenu("Main")

            # 创建动作并绑定 (关键修改2:指定父级为菜单栏)
            schools_action = QAction("Schools", menu_bar)
            schools_action.triggered.connect(self.show_schools_view)
            main_menu.addAction(schools_action)

            teachers_action = QAction("Teachers", menu_bar)
            teachers_action.triggered.connect(self.show_teachers_view)
            main_menu.addAction(teachers_action)

            users_action = QAction("Users", menu_bar)
            users_action.triggered.connect(self.show_users_view)
            main_menu.addAction(users_action)

            # 初始化视图和 Presenter
            self.init_views()

            # 设置中央部件 (关键修改3:使用 StackedWidget 管理视图切换)
            self.stacked_widget = QStackedWidget()
            self.stacked_widget.addWidget(self.school_view)
            self.stacked_widget.addWidget(self.teacher_view)
            self.stacked_widget.addWidget(self.user_view)
            self.main_window.setCentralWidget(self.stacked_widget)

            # 设置窗口属性
            self.main_window.setMinimumSize(800, 600)
            self.main_window.show()

        except Exception as e:
            import traceback
            traceback.print_exc()
            QMessageBox.critical(self, "Error", f"Failed to show main window: {str(e)}")

    def init_views(self):
        """
        初始化所有视图和 Presenter
        """
        from presentation.controllers.school import SchoolController
        from presentation.views.school import SchoolView
        from presentation.controllers.teacher import TeacherController
        from presentation.views.teacher import TeacherView
        from presentation.Presenter.school import SchoolPresenter
        from presentation.Presenter.teacher import TeacherPresenter
        from presentation.views.user import UserView
        from presentation.controllers.user import UserController
        from presentation.Presenter.user import UserPresenter

        # 学校视图
        self.school_view = SchoolView()
        school_controller = SchoolController()
        self.school_presenter = SchoolPresenter(self.school_view, school_controller)

        # 教师视图
        self.teacher_view = TeacherView()
        teacher_controller = TeacherController()
        self.teacher_presenter = TeacherPresenter(self.teacher_view, teacher_controller, school_controller)

        # 用户视图
        self.user_view = UserView()
        user_controller = UserController()
        self.user_presenter = UserPresenter(self.user_view, user_controller)

    def show_schools_view(self):
        self.school_view.show()
        self.teacher_view.hide()
        self.user_view.hide()

    def show_teachers_view(self):
        self.school_view.hide()
        self.teacher_view.show()
        self.user_view.hide()

    def show_users_view(self):
        self.school_view.hide()
        self.teacher_view.hide()
        self.user_view.show()






# encoding: utf-8
# 版权所有 2025 ©涂聚文有限公司 ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: python.exe -m pip install --upgrade pip
# pip install sqlalchemy  ORM DDD MVC pip install pymysql
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2023.1 python 3.11
# OS        : windows 10  https://doc.qt.io/qtforpython-6/PySide6/QtGui/QAction.html
# python.exe -m pip install --upgrade pip
# pip install pymysql  pip install SQLAlchemy
# pip3 install pyqt6
# pip install pyside6
# pip install pyqt6-tools
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  oracle 21c Neo4j
# Datetime  : 2025/3/20 20:32
# User      : geovindu
# Product   : PyCharm
# Project   : pyMySqlDDDOrmDemo
# File      : main.py
# explain   : 学习

import sys
from PyQt6.QtWidgets import QApplication, QTabWidget, QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton, QMessageBox,QMenuBar, QMenu, QMainWindow,QStackedWidget
from PyQt6.QtGui import QIcon
from PyQt6.QtGui import QAction
from PyQt6.QtSql import QSqlDatabase, QSqlQuery
from presentation.views.login import LoginWindow





if __name__ == '__main__':
    """
    """
    app = QApplication(sys.argv)
    app.setWindowIcon(QIcon('./favicon.ico'))
    login_window = LoginWindow()
    login_window.show()
    sys.exit(app.exec())
        """
        from presentation.controllers.school import SchoolController
        from presentation.views.school import SchoolView
        from presentation.controllers.teacher import TeacherController
        from presentation.views.teacher import TeacherView
        from presentation.Presenter.school import SchoolPresenter
        from presentation.Presenter.teacher import TeacherPresenter
        from presentation.views.user import UserView
        from presentation.controllers.user import UserController
        from presentation.Presenter.user import UserPresenter

        # 写在文件头
        from presentation.controllers import *
        from presentation.Presenter import *
        from presentation.views import *
        """
        from presentation.controllers import SchoolController,TeacherController,UserController
        from presentation.Presenter import SchoolPresenter,TeacherPresenter,UserPresenter
        from presentation.views import SchoolView,TeacherView,UserView

相关文章:

  • 用 Python 实现机器学习小项目:从入门到实战
  • Pyside6 信号与槽
  • 阿里云下一代可观测时序引擎-MetricStore 2.0
  • CPM:大规模生成式中文预训练语言模型
  • 从头开始运行一个yolo11的分类模型
  • MySQL响应慢是否由堵塞或死锁引起?
  • 端到端自动驾驶VLA模型:技术解析与模型设计
  • PostgreSQL数据库迁移到Docker拉取的pg镜像中的
  • 3.30 学习总结 Java 常用API+图形化界面
  • Linux系统中修改主机名及设置固定IP地址保姆级教程
  • UE5学习笔记 FPS游戏制作29 更换武器时更换武器的图标
  • 大模型LLMs基于Langchain+FAISS+Ollama/Deepseek/Qwen/OpenAI的RAG检索方法以及优化
  • Java图片加水印 实战demo
  • Linux中逻辑卷的使用、扩容与磁盘配额
  • LeetCode hot 100—排序链表
  • 通俗易懂的讲解SpringBean生命周期
  • 21-bfs-走迷宫(简单模板题)
  • 3132_nodejs_express后端框架
  • Spring中@Value的使用详解,以及和@ConfigurationProperties使用对比
  • 开源项目解读(https://github.com/zjunlp/DeepKE)
  • 计算机网络网站建设的实训总结/今天的新闻发布会
  • 新网站做seo优化步骤/企业qq
  • 空调公司网站建设/今日重大新闻头条十条
  • 网站开发外文文献/镇江网络
  • 辽宁省网站制作公司排名/网站关键词优化价格
  • 做网站的公司成都/百度快照手机版