Загрузка данных
import tkinter as tk
from tkinter import messagebox
class Slot:
def __init__(self, slot_id, dt_str):
self.id = slot_id
self.datetime = dt_str
self.status = "Свободен"
self.client_name = ""
class SlotManagerApp:
def __init__(self, root):
self.root = root
self.root.title("Система записи на приём по слотам времени")
self.root.geometry("650x450")
self.root.minsize(600, 400)
self.slots = []
self.counter_id = 1
self.create_widgets()
def create_widgets(self):
frame_add = tk.LabelFrame(
self.root, text=" 1. Создание нового слота ", padx=10, pady=10
)
frame_add.pack(fill="x", padx=10, pady=5)
tk.Label(frame_add, text="Дата и время (ДД.ММ.ГГГГ ЧЧ:ММ):").grid(
row=0, column=0, sticky="w", padx=5
)
self.entry_datetime = tk.Entry(frame_add, width=20)
self.entry_datetime.grid(row=0, column=1, padx=5)
self.entry_datetime.insert(0, "01.11.2026 10:00")
btn_add_slot = tk.Button(
frame_add,
text="Добавить слот",
command=self.add_slot,
bg="#e1f5fe",
cursor="hand2",
)
btn_add_slot.grid(row=0, column=2, padx=10)
frame_action = tk.LabelFrame(
self.root, text=" 2. Управление бронированием ", padx=10, pady=10
)
frame_action.pack(fill="x", padx=10, pady=5)
tk.Label(frame_action, text="ID слота:").grid(
row=0, column=0, sticky="w", padx=5
)
self.entry_slot_id = tk.Entry(frame_action, width=8)
self.entry_slot_id.grid(row=0, column=1, padx=5)
tk.Label(frame_action, text="ФИО клиента:").grid(
row=0, column=2, sticky="w", padx=5
)
self.entry_client = tk.Entry(frame_action, width=25)
self.entry_client.grid(row=0, column=3, padx=5)
btn_book = tk.Button(
frame_action,
text="Записаться",
command=self.book_slot,
bg="#e8f5e9",
cursor="hand2",
)
btn_book.grid(row=0, column=4, padx=5)
btn_cancel = tk.Button(
frame_action,
text="Отменить запись",
command=self.cancel_booking,
bg="#ffebee",
cursor="hand2",
)
btn_cancel.grid(row=0, column=5, padx=5)
frame_list = tk.LabelFrame(
self.root, text=" 3. Расписание и статусы слотов ", padx=10, pady=10
)
frame_list.pack(fill="both", expand=True, padx=10, pady=5)
self.listbox_slots = tk.Listbox(
frame_list, font=("Courier New", 10), width=75, height=10
)
self.listbox_slots.pack(
side="left", fill="both", expand=True, padx=(0, 5)
)
scrollbar = tk.Scrollbar(
frame_list, orient="vertical", command=self.listbox_slots.yview
)
scrollbar.pack(side="right", fill="y")
self.listbox_slots.config(yscrollcommand=scrollbar.set)
btn_refresh = tk.Button(
self.root, text="Обновить список", command=self.refresh_slots_list
)
btn_refresh.pack(pady=5)
def add_slot(self):
dt_str = self.entry_datetime.get().strip()
if not dt_str:
messagebox.showerror(
"Ошибка", "Поле даты и времени не может быть пустым"
)
return
new_slot = Slot(self.counter_id, dt_str)
self.slots.append(new_slot)
self.counter_id += 1
messagebox.showinfo("Успех", f"Слот №{new_slot.id} успешно добавлен")
self.refresh_slots_list()
def book_slot(self):
try:
slot_id = int(self.entry_slot_id.get().strip())
except ValueError:
messagebox.showerror("Ошибка", "ID слота должен быть целым числом")
return
client_name = self.entry_client.get().strip()
if len(client_name) < 3:
messagebox.showerror(
"Ошибка", "ФИО клиента должно содержать не менее 3 символов"
)
return
target_slot = None
for s in self.slots:
if s.id == slot_id:
target_slot = s
break
if not target_slot:
messagebox.showerror("Ошибка", f"Слот с ID {slot_id} не найден")
return
if target_slot.status == "Занят":
messagebox.showwarning(
"Внимание",
f"Слот №{slot_id} уже забронирован клиентом: {target_slot.client_name}",
)
return
target_slot.status = "Занят"
target_slot.client_name = client_name
messagebox.showinfo("Успех", f"Слот №{slot_id} успешно забронирован")
self.refresh_slots_list()
def cancel_booking(self):
try:
slot_id = int(self.entry_slot_id.get().strip())
except ValueError:
messagebox.showerror("Ошибка", "ID слота должен быть целым числом")
return
target_slot = None
for s in self.slots:
if s.id == slot_id:
target_slot = s
break
if not target_slot:
messagebox.showerror("Ошибка", f"Слот с ID {slot_id} не найден")
return
if target_slot.status == "Свободен":
messagebox.showinfo(
"Информация", f"Слот №{slot_id} уже свободен, отменять нечего"
)
return
target_slot.status = "Свободен"
target_slot.client_name = ""
messagebox.showinfo("Успех", f"Запись на слот №{slot_id} отменена")
self.refresh_slots_list()
def refresh_slots_list(self):
self.listbox_slots.delete(0, tk.END)
if not self.slots:
self.listbox_slots.insert(
tk.END, "Расписание пусто. Добавьте первый слот"
)
return
header = f"{'ID':<4} | {'Дата и время':<18} | {'Статус':<10} | {'Клиент'}"
self.listbox_slots.insert(tk.END, header)
self.listbox_slots.insert(tk.END, "-" * 60)
for s in self.slots:
client_info = s.client_name if s.client_name else "—"
row = f"{s.id:<4} | {s.datetime:<18} | {s.status:<10} | {client_info}"
self.listbox_slots.insert(tk.END, row)
if __name__ == "__main__":
root = tk.Tk()
app = SlotManagerApp(root)
root.mainloop()