Загрузка данных
import sys
import psycopg2
from PyQt6.QtWidgets import (
QApplication, QWidget, QLabel, QLineEdit, QPushButton,
QVBoxLayout, QHBoxLayout, QComboBox, QDateTimeEdit, QTextEdit,
QMessageBox, QStackedWidget, QTableWidget, QTableWidgetItem, QHeaderView
)
from PyQt6.QtCore import QDateTime
# =====================================================================
# НАСТРОЙКА ПОДКЛЮЧЕНИЯ К ВАШЕЙ СУЩЕСТВУЮЩЕЙ POSTGRESQL
# =====================================================================
DB_NAME = "medical_center"
DB_USER = "postgres"
DB_PASSWORD = "your_password" # <-- Впишите сюда ваш пароль от postgres
DB_HOST = "localhost"
DB_PORT = "5432"
connect = None
cursor = None
def init_db():
global connect, cursor
try:
# Простое подключение к вашей уже готовой базе данных
connect = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASSWORD, host=DB_HOST, port=DB_PORT)
# Гарантируем чтение русского текста без кракозябр
connect.set_client_encoding('UTF8')
cursor = connect.cursor()
print("Успешное подключение к существующей базе данных!")
except Exception as e:
print(f"Ошибка подключения к вашей БД: {e}")
sys.exit(1)
# =====================================================================
# ОКНО АВТОРИЗАЦИИ
# =====================================================================
class LoginWindow(QWidget):
def __init__(self, switch_window_callback):
super().__init__()
self.switch_window = switch_window_callback
self.init_ui()
def init_ui(self):
self.setWindowTitle('Авторизация')
self.resize(300, 180)
layout = QVBoxLayout()
self.login_input = QLineEdit(self)
self.login_input.setPlaceholderText('Логин')
layout.addWidget(self.login_input)
self.pass_input = QLineEdit(self)
self.pass_input.setPlaceholderText('Пароль')
self.pass_input.setEchoMode(QLineEdit.EchoMode.Password)
layout.addWidget(self.pass_input)
self.login_btn = QPushButton('Войти', self)
self.login_btn.clicked.connect(self.handle_login)
layout.addWidget(self.login_btn)
self.setLayout(layout)
def handle_login(self):
login = self.login_input.text()
password = self.pass_input.text()
try:
cursor.execute("SELECT role FROM users WHERE login=%s AND password=%s", (login, password))
result = cursor.fetchone()
if result:
# Извлекаем роль в нижнем регистре для точного сопоставления окон
role = str(result[0]).strip().lower()
QMessageBox.information(self, 'Успех', f'Вы вошли. Роль: {role}')
self.switch_window(role)
else:
QMessageBox.warning(self, 'Ошибка', 'Неверный логин или пароль')
except Exception as e:
QMessageBox.critical(self, 'Ошибка БД', f'{e}')
# =====================================================================
# ОКНО ПАЦИЕНТА (ЗАПИСЬ НА ПРИЕМ — МАКЕТ 1)
# =====================================================================
class PatientWindow(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
self.load_combobox()
def init_ui(self):
self.setWindowTitle('Окно добавления записи на прием')
self.resize(450, 480)
layout = QVBoxLayout()
title = QLabel('Окно добавления записи на прием')
title.setStyleSheet("font-size: 16px; font-weight: bold; margin-bottom: 10px;")
layout.addWidget(title)
layout.addWidget(QLabel('Выберите услугу:'))
self.comboBox = QComboBox(self)
layout.addWidget(self.comboBox)
layout.addWidget(QLabel('Выберите время:'))
self.dateTimeEdit = QDateTimeEdit(self)
self.dateTimeEdit.setDateTime(QDateTime.currentDateTime())
layout.addWidget(self.dateTimeEdit)
layout.addWidget(QLabel('Опишите проблему:'))
self.textEdit = QTextEdit(self)
self.textEdit.setPlaceholderText('Опишите проблему')
layout.addWidget(self.textEdit)
self.pushButton = QPushButton('Сохранить', self)
self.pushButton.clicked.connect(self.add_appointment)
layout.addWidget(self.pushButton)
self.setLayout(layout)
def load_combobox(self):
try:
self.comboBox.clear()
cursor.execute('SELECT id_type_product, name FROM type_products')
for id_type, name in cursor.fetchall():
self.comboBox.addItem(str(name), id_type)
except Exception as e:
print(f"Ошибка загрузки услуг: {e}")
def add_appointment(self):
try:
service_id = self.comboBox.currentData()
appointment_time = self.dateTimeEdit.dateTime().toString("yyyy-MM-dd HH:mm:ss")
problem_description = self.textEdit.toPlainText()
if not problem_description.strip():
QMessageBox.warning(self, 'Внимание', 'Пожалуйста, опишите проблему.')
return
cursor.execute(
"INSERT INTO appointments (id_type_product, appointment_time, problem_description) VALUES (%s, %s, %s)",
(service_id, appointment_time, problem_description)
)
connect.commit()
QMessageBox.information(self, 'Успех', 'Запись успешно сохранена!')
self.textEdit.clear()
except Exception as e:
QMessageBox.critical(self, 'Ошибка', f'{e}')
# =====================================================================
# ОКНО АДМИНИСТРАТОРА (ДОБАВЛЕНИЕ, РЕДАКТИРОВАНИЕ, УДАЛЕНИЕ — МАКЕТ 2)
# =====================================================================
class AdminWindow(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.setWindowTitle('Управление услугами (Панель Администратора)')
self.resize(450, 350)
layout = QVBoxLayout()
title = QLabel('Панель управления услугами клиники')
title.setStyleSheet("font-size: 16px; font-weight: bold; margin-bottom: 10px;")
layout.addWidget(title)
self.id_input = QLineEdit(self)
self.id_input.setPlaceholderText('ID Услуги (для Поиска, Изменения или Удаления)')
layout.addWidget(QLabel('Идентификатор услуги (ID):'))
layout.addWidget(self.id_input)
self.name_input = QLineEdit(self)
self.name_input.setPlaceholderText('Название медицинской услуги')
layout.addWidget(QLabel('Название услуги:'))
layout.addWidget(self.name_input)
btn_layout_1 = QHBoxLayout()
self.btn_add = QPushButton('Добавить новую', self)
self.btn_load = QPushButton('Загрузить по ID', self)
btn_layout_1.addWidget(self.btn_add)
btn_layout_1.addWidget(self.btn_load)
layout.addLayout(btn_layout_1)
btn_layout_2 = QHBoxLayout()
self.btn_save = QPushButton('Сохранить изменения', self)
self.btn_delete = QPushButton('Удалить услугу', self)
btn_layout_2.addWidget(self.btn_save)
btn_layout_2.addWidget(self.btn_delete)
layout.addLayout(btn_layout_2)
self.setLayout(layout)
self.btn_add.clicked.connect(self.add_service)
self.btn_load.clicked.connect(self.load_service)
self.btn_save.clicked.connect(self.save_service)
self.btn_delete.clicked.connect(self.delete_service)
def add_service(self):
name = self.name_input.text()
if not name.strip():
QMessageBox.warning(self, 'Ошибка', 'Введите название услуги')
return
try:
cursor.execute("INSERT INTO type_products (name) VALUES (%s)", (name,))
connect.commit()
QMessageBox.information(self, 'Успех', 'Новая услуга успешно добавлена!')
self.name_input.clear()
except Exception as e:
QMessageBox.critical(self, 'Ошибка', f'{e}')
def load_service(self):
id_serv = self.id_input.text()
if not id_serv.strip():
QMessageBox.warning(self, 'Ошибка', 'Введите ID услуги для поиска')
return
try:
cursor.execute("SELECT name FROM type_products WHERE id_type_product = %s", (id_serv,))
res = cursor.fetchone()
if res:
self.name_input.setText(str(res[0]))
QMessageBox.information(self, 'Успех', 'Данные услуги успешно загружены в форму')
else:
QMessageBox.warning(self, 'Ошибка', 'Услуга с таким ID не найдена')
except Exception as e:
QMessageBox.critical(self, 'Ошибка', f'{e}')
def save_service(self):
id_serv = self.id_input.text()
name = self.name_input.text()
if not id_serv.strip() or not name.strip():
QMessageBox.warning(self, 'Ошибка', 'Заполни поля ID и Название')
return
try:
cursor.execute("UPDATE type_products SET name = %s WHERE id_type_product = %s", (name, id_serv))
connect.commit()
QMessageBox.information(self, 'Успех', 'Название услуги успешно изменено')
except Exception as e:
QMessageBox.critical(self, 'Ошибка', f'{e}')
def delete_service(self):
id_serv = self.id_input.text()
if not id_serv.strip():
QMessageBox.warning(self, 'Ошибка', 'Укажите ID услуги для удаления')
return
try:
cursor.execute("DELETE FROM type_products WHERE id_type_product = %s", (id_serv,))
connect.commit()
QMessageBox.information(self, 'Успех', 'Услуга полностью удалена из базы')
self.id_input.clear()
self.name_input.clear()
except Exception as e:
QMessageBox.critical(self, 'Ошибка', f'{e}')
# =====================================================================
# ОКНО ВРАЧА (ВЫВОД ЗАПИСЕЙ В ТАБЛИЦУ)
# =====================================================================
class DoctorWindow(QWidget):
def __init__(self): # Исправлено: __init__ вместо init
super().__init__()
self.init_ui()
self.view_appointments()
def init_ui(self):
self.setWindowTitle('Панель Врача — Список приемов')
self.resize(600, 400)
layout = QVBoxLayout()
layout.addWidget(QLabel('Список активных записей пациентов на прием:'))
self.tableWidget = QTableWidget(self)
self.tableWidget.setColumnCount(3)
self.tableWidget.setHorizontalHeaderLabels(['Номер записи', 'Медицинская услуга', 'Дата и время приема'])
self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
layout.addWidget(self.tableWidget)
self.btn_refresh = QPushButton('Обновить список', self)
self.btn_refresh.clicked.connect(self.view_appointments)
layout.addWidget(self.btn_refresh)
self.setLayout(layout)
def view_appointments(self):
try:
cursor.execute('''
SELECT appointments.id, type_products.name, appointments.appointment_time
FROM appointments
JOIN type_products ON type_products.id_type_product = appointments.id_type_product
ORDER BY appointments.appointment_time DESC
''')
rows = cursor.fetchall()
self.tableWidget.setRowCount(0)
for row_idx, row_data in enumerate(rows):
self.tableWidget.insertRow(row_idx)
for col_idx, col_data in enumerate(row_data):
self.tableWidget.setItem(row_idx, col_idx, QTableWidgetItem(str(col_data)))
except Exception as e:
print(f"Ошибка вывода приемов: {e}")
# =====================================================================
# ГЛАВНЫЙ СТЕК-КОНТРОЛЛЕР ПРИЛОЖЕНИЯ (МЕНЕДЖЕР СМЕНЫ ОКОН)
# =====================================================================
class MainController:
def __init__(self): # Исправлено: __init__ вместо init
self.stacked_widget = QStackedWidget()
self.login_window = LoginWindow(self.switch_window)
self.stacked_widget.addWidget(self.login_window)
self.stacked_widget.setCurrentWidget(self.login_window)
self.stacked_widget.show()
def switch_window(self, role):
if role in ['пациент', 'patient']:
self.patient_window = PatientWindow()
self.stacked_widget.addWidget(self.patient_window)
self.stacked_widget.setCurrentWidget(self.patient_window)
elif role in ['администратор', 'admin']:
self.admin_window = AdminWindow()
self.stacked_widget.addWidget(self.admin_window)
self.stacked_widget.setCurrentWidget(self.admin_window)
elif role in ['врач', 'doctor']:
self.doctor_window = DoctorWindow()
self.stacked_widget.addWidget(self.doctor_window)
self.stacked_widget.setCurrentWidget(self.doctor_window)
else:
QMessageBox.critical(self.login_window, 'Ошибка', f'Роль "{role}" не поддерживается.')
if __name__ == '__main__': # Исправлено: добавлены двойные подчеркивания
app = QApplication(sys.argv)
init_db()
controller = MainController()
sys.exit(app.exec())
===============================================================================================
CREATE TABLE users (id SERIAL PRIMARY KEY, login VARCHAR(100), password VARCHAR(100) NOT NULL, role VARCHAR(50));
CREATE TABLE type_products (id_type_product SERIAL PRIMARY KEY, name VARCHAR(255));
CREATE TABLE appointments (id SERIAL PRIMARY KEY, id_type_product INT REFERENCES type_products(id_type_product), appointment_time TIMESTAMP, problem_description TEXT);
INSERT INTO users (login, password, role) VALUES ('admin', 'admin123', 'администратор'), ('doctor', 'doc123', 'врач'), ('patient', 'pat123', 'пациент');
INSERT INTO type_products (name) VALUES ('Прием терапевта'), ('УЗИ диагностика'), ('Консультация кардиолога');