import sys import sqlite3 from PyQt5.QtWidgets import ( QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QTableWidget, QTableWidgetItem, QPushButton, QComboBox, QLabel, QLineEdit, QMessageBox, QTabWidget, QFormLayout, QHeaderView, QAbstractItemView, QStatusBar, QSpinBox ) from PyQt5.QtCore import Qt class Database: """Класс для работы с базой данных SQLite""" def __init__(self, db_name="faculty.db"): self.db_name = db_name self.conn = None self.cursor = None self.connect() self.create_tables() self.populate_sample_data() def connect(self): """Подключение к базе данных""" self.conn = sqlite3.connect(self.db_name) self.cursor = self.conn.cursor() def create_tables(self): """Создание таблиц базы данных""" # Таблица факультетов self.cursor.execute(''' CREATE TABLE IF NOT EXISTS faculties ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, dean TEXT ) ''') # Таблица кафедр self.cursor.execute(''' CREATE TABLE IF NOT EXISTS departments ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, faculty_id INTEGER, head TEXT, FOREIGN KEY (faculty_id) REFERENCES faculties(id) ON DELETE CASCADE ) ''') # Таблица групп self.cursor.execute(''' CREATE TABLE IF NOT EXISTS groups ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, department_id INTEGER, course INTEGER, FOREIGN KEY (department_id) REFERENCES departments(id) ON DELETE CASCADE ) ''') # Таблица студентов self.cursor.execute(''' CREATE TABLE IF NOT EXISTS students ( id INTEGER PRIMARY KEY AUTOINCREMENT, last_name TEXT NOT NULL, first_name TEXT NOT NULL, middle_name TEXT, group_id INTEGER, birth_year INTEGER, email TEXT, FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE ) ''') self.conn.commit() def populate_sample_data(self): """Заполнение тестовыми данными (если таблицы пустые)""" self.cursor.execute("SELECT COUNT(*) FROM faculties") if self.cursor.fetchone()[0] > 0: return # Факультеты faculties = [ ("Информатика и вычислительная техника", "Иванов И.И."), ("Экономика и управление", "Петров П.П."), ("Инфокоммуникационные технологии", "Сидоров С.С.") ] self.cursor.executemany("INSERT INTO faculties (name, dean) VALUES (?, ?)", faculties) # Кафедры departments = [ ("Программная инженерия", 1, "Козлов А.А."), ("Информационные системы", 1, "Новиков Б.Б."), ("Менеджмент", 2, "Смирнова В.В."), ("Сети связи", 3, "Федоров Г.Г.") ] self.cursor.executemany( "INSERT INTO departments (name, faculty_id, head) VALUES (?, ?, ?)", departments ) # Группы groups = [ ("ПИ-21", 1, 3), ("ПИ-22", 1, 2), ("ИС-21", 2, 3), ("М-21", 3, 3), ("СС-21", 4, 3) ] self.cursor.executemany( "INSERT INTO groups (name, department_id, course) VALUES (?, ?, ?)", groups ) # Студенты students = [ ("Александров", "Алексей", "Андреевич", 1, 2003, "alex@mail.ru"), ("Борисова", "Бэлла", "Борисовна", 1, 2004, "bella@mail.ru"), ("Васильев", "Виктор", "Владимирович", 2, 2004, "victor@mail.ru"), ("Григорьева", "Галина", "Геннадьевна", 2, 2003, "galina@mail.ru"), ("Дмитриев", "Денис", "Дмитриевич", 3, 2003, "denis@mail.ru"), ("Егорова", "Елена", "Евгеньевна", 3, 2004, "elena@mail.ru"), ("Жуков", "Захар", "Зиновьевич", 4, 2003, "zahar@mail.ru"), ("Иванова", "Ирина", "Игоревна", 4, 2004, "irina@mail.ru"), ("Кузнецов", "Кирилл", "Константинович", 5, 2003, "kirill@mail.ru"), ("Лебедева", "Любовь", "Леонидовна", 5, 2004, "lubov@mail.ru"), ] self.cursor.executemany( "INSERT INTO students (last_name, first_name, middle_name, group_id, birth_year, email) VALUES (?, ?, ?, ?, ?, ?)", students ) self.conn.commit() # === CRUD операции для факультетов === def get_faculties(self): self.cursor.execute("SELECT * FROM faculties ORDER BY name") return self.cursor.fetchall() def add_faculty(self, name, dean): self.cursor.execute("INSERT INTO faculties (name, dean) VALUES (?, ?)", (name, dean)) self.conn.commit() return self.cursor.lastrowid def update_faculty(self, id, name, dean): self.cursor.execute("UPDATE faculties SET name=?, dean=? WHERE id=?", (name, dean, id)) self.conn.commit() def delete_faculty(self, id): self.cursor.execute("DELETE FROM faculties WHERE id=?", (id,)) self.conn.commit() # === CRUD операции для кафедр === def get_departments(self, faculty_id=None): if faculty_id: self.cursor.execute(""" SELECT d.id, d.name, d.faculty_id, d.head, f.name as faculty_name FROM departments d JOIN faculties f ON d.faculty_id = f.id WHERE d.faculty_id = ? ORDER BY d.name """, (faculty_id,)) else: self.cursor.execute(""" SELECT d.id, d.name, d.faculty_id, d.head, f.name as faculty_name FROM departments d JOIN faculties f ON d.faculty_id = f.id ORDER BY d.name """) return self.cursor.fetchall() def add_department(self, name, faculty_id, head): self.cursor.execute( "INSERT INTO departments (name, faculty_id, head) VALUES (?, ?, ?)", (name, faculty_id, head) ) self.conn.commit() return self.cursor.lastrowid def update_department(self, id, name, faculty_id, head): self.cursor.execute( "UPDATE departments SET name=?, faculty_id=?, head=? WHERE id=?", (name, faculty_id, head, id) ) self.conn.commit() def delete_department(self, id): self.cursor.execute("DELETE FROM departments WHERE id=?", (id,)) self.conn.commit() # === CRUD операции для групп === def get_groups(self, department_id=None): if department_id: self.cursor.execute(""" SELECT g.id, g.name, g.department_id, g.course, d.name as department_name FROM groups g JOIN departments d ON g.department_id = d.id WHERE g.department_id = ? ORDER BY g.name """, (department_id,)) else: self.cursor.execute(""" SELECT g.id, g.name, g.department_id, g.course, d.name as department_name FROM groups g JOIN departments d ON g.department_id = d.id ORDER BY g.name """) return self.cursor.fetchall() def add_group(self, name, department_id, course): self.cursor.execute( "INSERT INTO groups (name, department_id, course) VALUES (?, ?, ?)", (name, department_id, course) ) self.conn.commit() return self.cursor.lastrowid def update_group(self, id, name, department_id, course): self.cursor.execute( "UPDATE groups SET name=?, department_id=?, course=? WHERE id=?", (name, department_id, course, id) ) self.conn.commit() def delete_group(self, id): self.cursor.execute("DELETE FROM groups WHERE id=?", (id,)) self.conn.commit() # === CRUD операции для студентов === def get_students(self, group_id=None, search_query=None): if search_query: query = """ SELECT s.id, s.last_name, s.first_name, s.middle_name, s.group_id, s.birth_year, s.email, g.name as group_name FROM students s JOIN groups g ON s.group_id = g.id WHERE s.last_name LIKE ? OR s.first_name LIKE ? OR s.middle_name LIKE ? ORDER BY s.last_name, s.first_name """ search = f"%{search_query}%" self.cursor.execute(query, (search, search, search)) elif group_id: self.cursor.execute(""" SELECT s.id, s.last_name, s.first_name, s.middle_name, s.group_id, s.birth_year, s.email, g.name as group_name FROM students s JOIN groups g ON s.group_id = g.id WHERE s.group_id = ? ORDER BY s.last_name, s.first_name """, (group_id,)) else: self.cursor.execute(""" SELECT s.id, s.last_name, s.first_name, s.middle_name, s.group_id, s.birth_year, s.email, g.name as group_name FROM students s JOIN groups g ON s.group_id = g.id ORDER BY s.last_name, s.first_name """) return self.cursor.fetchall() def add_student(self, last_name, first_name, middle_name, group_id, birth_year, email): self.cursor.execute( "INSERT INTO students (last_name, first_name, middle_name, group_id, birth_year, email) VALUES (?, ?, ?, ?, ?, ?)", (last_name, first_name, middle_name, group_id, birth_year, email) ) self.conn.commit() return self.cursor.lastrowid def update_student(self, id, last_name, first_name, middle_name, group_id, birth_year, email): self.cursor.execute( "UPDATE students SET last_name=?, first_name=?, middle_name=?, group_id=?, birth_year=?, email=? WHERE id=?", (last_name, first_name, middle_name, group_id, birth_year, email, id) ) self.conn.commit() def delete_student(self, id): self.cursor.execute("DELETE FROM students WHERE id=?", (id,)) self.conn.commit() def search_student_exact(self, last_name): """Поиск студента по точной фамилии""" self.cursor.execute(""" SELECT s.id, s.last_name, s.first_name, s.middle_name, s.group_id, s.birth_year, s.email, g.name as group_name FROM students s JOIN groups g ON s.group_id = g.id WHERE s.last_name = ? ORDER BY s.first_name """, (last_name,)) return self.cursor.fetchall() def close(self): if self.conn: self.conn.close() class MainWindow(QMainWindow): """Главное окно приложения""" def __init__(self): super().__init__() self.setWindowTitle("Лабораторная работа №3 - База данных «Факультет»") self.setMinimumSize(1100, 700) # Инициализация базы данных self.db = Database() # Создание интерфейса self.init_ui() # Загрузка данных self.load_all_data() def init_ui(self): """Инициализация интерфейса""" central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) # Верхняя панель - поиск студентов search_group = QGroupBox("Поиск студентов") search_layout = QHBoxLayout(search_group) search_layout.addWidget(QLabel("Фамилия:")) self.search_input = QLineEdit() self.search_input.setPlaceholderText("Введите фамилию для поиска...") self.search_input.returnPressed.connect(self.search_students) search_layout.addWidget(self.search_input) self.btn_search = QPushButton("Поиск (частичный)") self.btn_search.clicked.connect(self.search_students) search_layout.addWidget(self.btn_search) self.btn_search_exact = QPushButton("Точный поиск") self.btn_search_exact.clicked.connect(self.search_students_exact) search_layout.addWidget(self.btn_search_exact) self.btn_reset_search = QPushButton("Сбросить") self.btn_reset_search.clicked.connect(self.reset_search) search_layout.addWidget(self.btn_reset_search) main_layout.addWidget(search_group) # Вкладки для разных таблиц self.tabs = QTabWidget() main_layout.addWidget(self.tabs) # Вкладка студентов self.create_students_tab() # Вкладка групп self.create_groups_tab() # Вкладка кафедр self.create_departments_tab() # Вкладка факультетов self.create_faculties_tab() # Статусбар self.statusBar = QStatusBar() self.setStatusBar(self.statusBar) self.statusBar.showMessage("Готово") def create_students_tab(self): """Создание вкладки студентов""" tab = QWidget() layout = QVBoxLayout(tab) # Фильтр по группе filter_layout = QHBoxLayout() filter_layout.addWidget(QLabel("Фильтр по группе:")) self.students_group_filter = QComboBox() self.students_group_filter.currentIndexChanged.connect(self.filter_students_by_group) filter_layout.addWidget(self.students_group_filter) filter_layout.addStretch() layout.addLayout(filter_layout) # Таблица студентов self.students_table = QTableWidget() self.students_table.setColumnCount(7) self.students_table.setHorizontalHeaderLabels([ "ID", "Фамилия", "Имя", "Отчество", "Группа", "Год рождения", "Email" ]) self.students_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.students_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.students_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.students_table.setColumnHidden(0, True) # Скрываем ID layout.addWidget(self.students_table) # Форма редактирования form_group = QGroupBox("Добавить/Редактировать студента") form_layout = QFormLayout(form_group) self.student_last_name = QLineEdit() self.student_first_name = QLineEdit() self.student_middle_name = QLineEdit() self.student_group = QComboBox() self.student_birth_year = QSpinBox() self.student_birth_year.setRange(1990, 2010) self.student_birth_year.setValue(2003) self.student_email = QLineEdit() form_layout.addRow("Фамилия:", self.student_last_name) form_layout.addRow("Имя:", self.student_first_name) form_layout.addRow("Отчество:", self.student_middle_name) form_layout.addRow("Группа:", self.student_group) form_layout.addRow("Год рождения:", self.student_birth_year) form_layout.addRow("Email:", self.student_email) layout.addWidget(form_group) # Кнопки управления buttons_layout = QHBoxLayout() btn_add = QPushButton("Добавить") btn_add.clicked.connect(self.add_student) btn_edit = QPushButton("Изменить выбранного") btn_edit.clicked.connect(self.edit_student) btn_delete = QPushButton("Удалить выбранного") btn_delete.clicked.connect(self.delete_student) btn_load = QPushButton("Загрузить в форму") btn_load.clicked.connect(self.load_student_to_form) buttons_layout.addWidget(btn_add) buttons_layout.addWidget(btn_edit) buttons_layout.addWidget(btn_delete) buttons_layout.addWidget(btn_load) buttons_layout.addStretch() layout.addLayout(buttons_layout) self.tabs.addTab(tab, "Студенты") def create_groups_tab(self): """Создание вкладки групп""" tab = QWidget() layout = QVBoxLayout(tab) # Фильтр по кафедре filter_layout = QHBoxLayout() filter_layout.addWidget(QLabel("Фильтр по кафедре:")) self.groups_dept_filter = QComboBox() self.groups_dept_filter.currentIndexChanged.connect(self.filter_groups_by_department) filter_layout.addWidget(self.groups_dept_filter) filter_layout.addStretch() layout.addLayout(filter_layout) # Таблица групп self.groups_table = QTableWidget() self.groups_table.setColumnCount(4) self.groups_table.setHorizontalHeaderLabels(["ID", "Название", "Кафедра", "Курс"]) self.groups_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.groups_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.groups_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.groups_table.setColumnHidden(0, True) layout.addWidget(self.groups_table) # Форма редактирования form_group = QGroupBox("Добавить/Редактировать группу") form_layout = QFormLayout(form_group) self.group_name = QLineEdit() self.group_department = QComboBox() self.group_course = QSpinBox() self.group_course.setRange(1, 6) self.group_course.setValue(1) form_layout.addRow("Название:", self.group_name) form_layout.addRow("Кафедра:", self.group_department) form_layout.addRow("Курс:", self.group_course) layout.addWidget(form_group) # Кнопки buttons_layout = QHBoxLayout() btn_add = QPushButton("Добавить") btn_add.clicked.connect(self.add_group) btn_edit = QPushButton("Изменить") btn_edit.clicked.connect(self.edit_group) btn_delete = QPushButton("Удалить") btn_delete.clicked.connect(self.delete_group) btn_load = QPushButton("Загрузить в форму") btn_load.clicked.connect(self.load_group_to_form) buttons_layout.addWidget(btn_add) buttons_layout.addWidget(btn_edit) buttons_layout.addWidget(btn_delete) buttons_layout.addWidget(btn_load) buttons_layout.addStretch() layout.addLayout(buttons_layout) self.tabs.addTab(tab, "Группы") def create_departments_tab(self): """Создание вкладки кафедр""" tab = QWidget() layout = QVBoxLayout(tab) # Фильтр по факультету filter_layout = QHBoxLayout() filter_layout.addWidget(QLabel("Фильтр по факультету:")) self.depts_faculty_filter = QComboBox() self.depts_faculty_filter.currentIndexChanged.connect(self.filter_departments_by_faculty) filter_layout.addWidget(self.depts_faculty_filter) filter_layout.addStretch() layout.addLayout(filter_layout) # Таблица кафедр self.departments_table = QTableWidget() self.departments_table.setColumnCount(4) self.departments_table.setHorizontalHeaderLabels(["ID", "Название", "Факультет", "Заведующий"]) self.departments_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.departments_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.departments_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.departments_table.setColumnHidden(0, True) layout.addWidget(self.departments_table) # Форма редактирования form_group = QGroupBox("Добавить/Редактировать кафедру") form_layout = QFormLayout(form_group) self.dept_name = QLineEdit() self.dept_faculty = QComboBox() self.dept_head = QLineEdit() form_layout.addRow("Название:", self.dept_name) form_layout.addRow("Факультет:", self.dept_faculty) form_layout.addRow("Заведующий:", self.dept_head) layout.addWidget(form_group) # Кнопки buttons_layout = QHBoxLayout() btn_add = QPushButton("Добавить") btn_add.clicked.connect(self.add_department) btn_edit = QPushButton("Изменить") btn_edit.clicked.connect(self.edit_department) btn_delete = QPushButton("Удалить") btn_delete.clicked.connect(self.delete_department) btn_load = QPushButton("Загрузить в форму") btn_load.clicked.connect(self.load_department_to_form) buttons_layout.addWidget(btn_add) buttons_layout.addWidget(btn_edit) buttons_layout.addWidget(btn_delete) buttons_layout.addWidget(btn_load) buttons_layout.addStretch() layout.addLayout(buttons_layout) self.tabs.addTab(tab, "Кафедры") def create_faculties_tab(self): """Создание вкладки факультетов""" tab = QWidget() layout = QVBoxLayout(tab) # Таблица факультетов self.faculties_table = QTableWidget() self.faculties_table.setColumnCount(3) self.faculties_table.setHorizontalHeaderLabels(["ID", "Название", "Декан"]) self.faculties_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.faculties_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.faculties_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) self.faculties_table.setColumnHidden(0, True) layout.addWidget(self.faculties_table) # Форма редактирования form_group = QGroupBox("Добавить/Редактировать факультет") form_layout = QFormLayout(form_group) self.faculty_name = QLineEdit() self.faculty_dean = QLineEdit() form_layout.addRow("Название:", self.faculty_name) form_layout.addRow("Декан:", self.faculty_dean) layout.addWidget(form_group) # Кнопки buttons_layout = QHBoxLayout() btn_add = QPushButton("Добавить") btn_add.clicked.connect(self.add_faculty) btn_edit = QPushButton("Изменить") btn_edit.clicked.connect(self.edit_faculty) btn_delete = QPushButton("Удалить") btn_delete.clicked.connect(self.delete_faculty) btn_load = QPushButton("Загрузить в форму") btn_load.clicked.connect(self.load_faculty_to_form) buttons_layout.addWidget(btn_add) buttons_layout.addWidget(btn_edit) buttons_layout.addWidget(btn_delete) buttons_layout.addWidget(btn_load) buttons_layout.addStretch() layout.addLayout(buttons_layout) self.tabs.addTab(tab, "Факультеты") def load_all_data(self): """Загрузка всех данных""" self.load_faculties() self.load_departments() self.load_groups() self.load_students() self.update_comboboxes() def update_comboboxes(self): """Обновление выпадающих списков""" # Факультеты faculties = self.db.get_faculties() self.depts_faculty_filter.clear() self.depts_faculty_filter.addItem("Все факультеты", None) self.dept_faculty.clear() for f in faculties: self.depts_faculty_filter.addItem(f[1], f[0]) self.dept_faculty.addItem(f[1], f[0]) # Кафедры departments = self.db.get_departments() self.groups_dept_filter.clear() self.groups_dept_filter.addItem("Все кафедры", None) self.group_department.clear() for d in departments: self.groups_dept_filter.addItem(d[1], d[0]) self.group_department.addItem(d[1], d[0]) # Группы groups = self.db.get_groups() self.students_group_filter.clear() self.students_group_filter.addItem("Все группы", None) self.student_group.clear() for g in groups: self.students_group_filter.addItem(g[1], g[0]) self.student_group.addItem(g[1], g[0]) # === Факультеты === def load_faculties(self): faculties = self.db.get_faculties() self.faculties_table.setRowCount(len(faculties)) for row, f in enumerate(faculties): self.faculties_table.setItem(row, 0, QTableWidgetItem(str(f[0]))) self.faculties_table.setItem(row, 1, QTableWidgetItem(f[1])) self.faculties_table.setItem(row, 2, QTableWidgetItem(f[2] or "")) def add_faculty(self): name = self.faculty_name.text().strip() dean = self.faculty_dean.text().strip() if not name: QMessageBox.warning(self, "Ошибка", "Введите название факультета") return try: self.db.add_faculty(name, dean) self.load_all_data() self.faculty_name.clear() self.faculty_dean.clear() self.statusBar.showMessage("Факультет добавлен") except Exception as e: QMessageBox.critical(self, "Ошибка", str(e)) def edit_faculty(self): row = self.faculties_table.currentRow() if row < 0: QMessageBox.warning(self, "Ошибка", "Выберите факультет") return id = int(self.faculties_table.item(row, 0).text()) name = self.faculty_name.text().strip() dean = self.faculty_dean.text().strip() if not name: QMessageBox.warning(self, "Ошибка", "Введите название факультета") return self.db.update_faculty(id, name, dean) self.load_all_data() self.statusBar.showMessage("Факультет обновлен") def delete_faculty(self): row = self.faculties_table.currentRow() if row < 0: QMessageBox.warning(self, "Ошибка", "Выберите факультет") return reply = QMessageBox.question(self, "Подтверждение", "Удалить факультет? Это также удалит все связанные кафедры, группы и студентов.", QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: id = int(self.faculties_table.item(row, 0).text()) self.db.delete_faculty(id) self.load_all_data() self.statusBar.showMessage("Факультет удален") def load_faculty_to_form(self): row = self.faculties_table.currentRow() if row < 0: return self.faculty_name.setText(self.faculties_table.item(row, 1).text()) self.faculty_dean.setText(self.faculties_table.item(row, 2).text()) # === Кафедры === def load_departments(self, faculty_id=None): departments = self.db.get_departments(faculty_id) self.departments_table.setRowCount(len(departments)) for row, d in enumerate(departments): self.departments_table.setItem(row, 0, QTableWidgetItem(str(d[0]))) self.departments_table.setItem(row, 1, QTableWidgetItem(d[1])) self.departments_table.setItem(row, 2, QTableWidgetItem(d[4])) # faculty_name self.departments_table.setItem(row, 3, QTableWidgetItem(d[3] or "")) def filter_departments_by_faculty(self): faculty_id = self.depts_faculty_filter.currentData() self.load_departments(faculty_id) def add_department(self): name = self.dept_name.text().strip() faculty_id = self.dept_faculty.currentData() head = self.dept_head.text().strip() if not name or not faculty_id: QMessageBox.warning(self, "Ошибка", "Заполните все обязательные поля") return self.db.add_department(name, faculty_id, head) self.load_all_data() self.dept_name.clear() self.dept_head.clear() self.statusBar.showMessage("Кафедра добавлена") def edit_department(self): row = self.departments_table.currentRow() if row < 0: QMessageBox.warning(self, "Ошибка", "Выберите кафедру") return id = int(self.departments_table.item(row, 0).text()) name = self.dept_name.text().strip() faculty_id = self.dept_faculty.currentData() head = self.dept_head.text().strip() if not name or not faculty_id: QMessageBox.warning(self, "Ошибка", "Заполните все обязательные поля") return self.db.update_department(id, name, faculty_id, head) self.load_all_data() self.statusBar.showMessage("Кафедра обновлена") def delete_department(self): row = self.departments_table.currentRow() if row < 0: QMessageBox.warning(self, "Ошибка", "Выберите кафедру") return reply = QMessageBox.question(self, "Подтверждение", "Удалить кафедру? Это также удалит все связанные группы и студентов.", QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: id = int(self.departments_table.item(row, 0).text()) self.db.delete_department(id) self.load_all_data() self.statusBar.showMessage("Кафедра удалена") def load_department_to_form(self): row = self.departments_table.currentRow() if row < 0: return self.dept_name.setText(self.departments_table.item(row, 1).text()) self.dept_head.setText(self.departments_table.item(row, 3).text()) # Найти факультет в комбобоксе faculty_name = self.departments_table.item(row, 2).text() index = self.dept_faculty.findText(faculty_name) if index >= 0: self.dept_faculty.setCurrentIndex(index) # === Группы === def load_groups(self, department_id=None): groups = self.db.get_groups(department_id) self.groups_table.setRowCount(len(groups)) for row, g in enumerate(groups): self.groups_table.setItem(row, 0, QTableWidgetItem(str(g[0]))) self.groups_table.setItem(row, 1, QTableWidgetItem(g[1])) self.groups_table.setItem(row, 2, QTableWidgetItem(g[4])) # department_name self.groups_table.setItem(row, 3, QTableWidgetItem(str(g[3]))) def filter_groups_by_department(self): dept_id = self.groups_dept_filter.currentData() self.load_groups(dept_id) def add_group(self): name = self.group_name.text().strip() dept_id = self.group_department.currentData() course = self.group_course.value() if not name or not dept_id: QMessageBox.warning(self, "Ошибка", "Заполните все обязательные поля") return self.db.add_group(name, dept_id, course) self.load_all_data() self.group_name.clear() self.statusBar.showMessage("Группа добавлена") def edit_group(self): row = self.groups_table.currentRow() if row < 0: QMessageBox.warning(self, "Ошибка", "Выберите группу") return id = int(self.groups_table.item(row, 0).text()) name = self.group_name.text().strip() dept_id = self.group_department.currentData() course = self.group_course.value() if not name or not dept_id: QMessageBox.warning(self, "Ошибка", "Заполните все обязательные поля") return self.db.update_group(id, name, dept_id, course) self.load_all_data() self.statusBar.showMessage("Группа обновлена") def delete_group(self): row = self.groups_table.currentRow() if row < 0: QMessageBox.warning(self, "Ошибка", "Выберите группу") return reply = QMessageBox.question(self, "Подтверждение", "Удалить группу? Это также удалит всех студентов группы.", QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: id = int(self.groups_table.item(row, 0).text()) self.db.delete_group(id) self.load_all_data() self.statusBar.showMessage("Группа удалена") def load_group_to_form(self): row = self.groups_table.currentRow() if row < 0: return self.group_name.setText(self.groups_table.item(row, 1).text()) self.group_course.setValue(int(self.groups_table.item(row, 3).text())) dept_name = self.groups_table.item(row, 2).text() index = self.group_department.findText(dept_name) if index >= 0: self.group_department.setCurrentIndex(index) # === Студенты === def load_students(self, group_id=None, search_query=None): students = self.db.get_students(group_id, search_query) self.students_table.setRowCount(len(students)) for row, s in enumerate(students): self.students_table.setItem(row, 0, QTableWidgetItem(str(s[0]))) self.students_table.setItem(row, 1, QTableWidgetItem(s[1])) self.students_table.setItem(row, 2, QTableWidgetItem(s[2])) self.students_table.setItem(row, 3, QTableWidgetItem(s[3] or "")) self.students_table.setItem(row, 4, QTableWidgetItem(s[7])) # group_name self.students_table.setItem(row, 5, QTableWidgetItem(str(s[5]))) self.students_table.setItem(row, 6, QTableWidgetItem(s[6] or "")) def filter_students_by_group(self): group_id = self.students_group_filter.currentData() self.load_students(group_id) def search_students(self): query = self.search_input.text().strip() if query: self.load_students(search_query=query) self.statusBar.showMessage(f"Поиск: {query}") else: self.load_students() def search_students_exact(self): query = self.search_input.text().strip() if query: students = self.db.search_student_exact(query) self.students_table.setRowCount(len(students)) for row, s in enumerate(students): self.students_table.setItem(row, 0, QTableWidgetItem(str(s[0]))) self.students_table.setItem(row, 1, QTableWidgetItem(s[1])) self.students_table.setItem(row, 2, QTableWidgetItem(s[2])) self.students_table.setItem(row, 3, QTableWidgetItem(s[3] or "")) self.students_table.setItem(row, 4, QTableWidgetItem(s[7])) self.students_table.setItem(row, 5, QTableWidgetItem(str(s[5]))) self.students_table.setItem(row, 6, QTableWidgetItem(s[6] or "")) self.statusBar.showMessage(f"Точный поиск: {query} (найдено: {len(students)})") def reset_search(self): self.search_input.clear() self.students_group_filter.setCurrentIndex(0) self.load_students() self.statusBar.showMessage("Поиск сброшен") def add_student(self): last_name = self.student_last_name.text().strip() first_name = self.student_first_name.text().strip() middle_name = self.student_middle_name.text().strip() group_id = self.student_group.currentData() birth_year = self.student_birth_year.value() email = self.student_email.text().strip() if not last_name or not first_name or not group_id: QMessageBox.warning(self, "Ошибка", "Заполните обязательные поля (Фамилия, Имя, Группа)") return self.db.add_student(last_name, first_name, middle_name, group_id, birth_year, email) self.load_students() self.clear_student_form() self.statusBar.showMessage("Студент добавлен") def edit_student(self): row = self.students_table.currentRow() if row < 0: QMessageBox.warning(self, "Ошибка", "Выберите студента") return id = int(self.students_table.item(row, 0).text()) last_name = self.student_last_name.text().strip() first_name = self.student_first_name.text().strip() middle_name = self.student_middle_name.text().strip() group_id = self.student_group.currentData() birth_year = self.student_birth_year.value() email = self.student_email.text().strip() if not last_name or not first_name or not group_id: QMessageBox.warning(self, "Ошибка", "Заполните обязательные поля") return self.db.update_student(id, last_name, first_name, middle_name, group_id, birth_year, email) self.load_students() self.statusBar.showMessage("Студент обновлен") def delete_student(self): row = self.students_table.currentRow() if row < 0: QMessageBox.warning(self, "Ошибка", "Выберите студента") return reply = QMessageBox.question(self, "Подтверждение", "Удалить студента?", QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: id = int(self.students_table.item(row, 0).text()) self.db.delete_student(id) self.load_students() self.statusBar.showMessage("Студент удален") def load_student_to_form(self): row = self.students_table.currentRow() if row < 0: return self.student_last_name.setText(self.students_table.item(row, 1).text()) self.student_first_name.setText(self.students_table.item(row, 2).text()) self.student_middle_name.setText(self.students_table.item(row, 3).text()) self.student_birth_year.setValue(int(self.students_table.item(row, 5).text())) self.student_email.setText(self.students_table.item(row, 6).text()) # Найти группу group_name = self.students_table.item(row, 4).text() index = self.student_group.findText(group_name) if index >= 0: self.student_group.setCurrentIndex(index) def clear_student_form(self): self.student_last_name.clear() self.student_first_name.clear() self.student_middle_name.clear() self.student_email.clear() self.student_birth_year.setValue(2003) def closeEvent(self, event): """Закрытие приложения""" self.db.close() event.accept() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())