финал
This commit is contained in:
BIN
visuapPart1/thirdLabVisualProg/faculty.db
Normal file
BIN
visuapPart1/thirdLabVisualProg/faculty.db
Normal file
Binary file not shown.
968
visuapPart1/thirdLabVisualProg/main.py
Normal file
968
visuapPart1/thirdLabVisualProg/main.py
Normal 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_())
|
||||
2
visuapPart1/thirdLabVisualProg/requirements.txt
Normal file
2
visuapPart1/thirdLabVisualProg/requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
PyQt5>=5.15.0
|
||||
pyinstaller>=6.0.0
|
||||
Reference in New Issue
Block a user