Сделал лабы + контрольную

This commit is contained in:
2025-12-11 14:26:39 +03:00
parent fe28b9a58c
commit 7fd78c0de2
7 changed files with 2012 additions and 0 deletions

Binary file not shown.

968
thirdLabVisualProg/main.py Normal file
View File

@@ -0,0 +1,968 @@
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_())

View File

@@ -0,0 +1,2 @@
PyQt5>=5.15.0
pyinstaller>=6.0.0