Швидкі Нотатки

Ціна
40 ₴
Автор
Denys 2026
Категорія
Інше

Опис

import tkinter as tk

import json

import os

DATA_FILE = "app_data.json"

class NotesApp:

def init(self, root):

self.root = root

self.root.title("Нотатки")

self.root.geometry("380x680")

self.root.configure(bg="#121212")

self.lang = "uk"

self.account = None

self.notes = []

self.current_hour = 0

self.current_minute = 0

self.translations = {

"uk": {

"title": "НОТАТКИ",

"login_btn": "УВІЙТИ ЧЕРЕЗ ГУГЛ",

"choose_acc": "Оберіть обліковий запис Гугл",

"no_notes": "НЕМАЄ НОТАТОК",

"menu": "Меню",

"logout": "ВИЙТИ",

"logout_save": "ВИЙТИ ТА ЗБЕРЕГТИ",

"lang_btn": "МОВА: Українська",

"back": "НАЗАД",

"create_title": "СТВОРЕННЯ НОТАТКИ",

"time_label": "Час:",

"save": "ЗБЕРЕГТИ НОТАТКУ",

"placeholder": "Введіть текст..."

},

"en": {

"title": "NOTES",

"login_btn": "SIGN IN WITH GOOGLE",

"choose_acc": "Choose Google Account",

"no_notes": "NO NOTES",

"menu": "Menu",

"logout": "LOG OUT",

"logout_save": "LOG OUT & SAVE",

"lang_btn": "LANGUAGE: English",

"back": "BACK",

"create_title": "CREATE NOTE",

"time_label": "Time:",

"save": "SAVE NOTE",

"placeholder": "Enter text..."

}

}

self.load_data()

self.build_ui()

if self.account:

self.show_main_screen()

else:

self.show_login_screen()

def load_data(self):

if os.path.exists(DATA_FILE):

try:

with open(DATA_FILE, "r", encoding="utf-8") as f:

data = json.load(f)

self.account = data.get("account")

self.notes = data.get("notes", [])

self.lang = data.get("lang", "uk")

except Exception:

pass

def save_data(self):

data = {

"account": self.account,

"notes": self.notes,

"lang": self.lang

}

with open(DATA_FILE, "w", encoding="utf-8") as f:

json.dump(data, f, ensure_ascii=False, indent=4)

def t(self, key):

return self.translations[self.lang].get(key, "")

def build_ui(self):

# 1. Екран входу

self.login_frame = tk.Frame(self.root, bg="#121212")

self.lbl_title = tk.Label(self.login_frame, text=self.t("title"), fg="#ff8c00", bg="#121212", font=("Arial", 28, "bold"))

self.lbl_title.pack(pady=(180, 40))

self.btn_google = tk.Button(self.login_frame, text=self.t("login_btn"), bg="#2e7d32", fg="white", font=("Arial", 12, "bold"), bd=0, padx=20, pady=12, command=self.open_google_modal)

self.btn_google.pack()

# 2. Головний екран

self.main_frame = tk.Frame(self.root, bg="#1a1a1a")

self.header = tk.Frame(self.main_frame, bg="#1a1a1a")

self.header.pack(fill="x", padx=15, pady=15)

# Ліва частина шапки: заголовок + пошта

left_header = tk.Frame(self.header, bg="#1a1a1a")

left_header.pack(side="left")

self.lbl_header = tk.Label(left_header, text=self.t("title"), fg="#2e7d32", bg="#1a1a1a", font=("Arial", 16, "bold"))

self.lbl_header.pack(anchor="w")

self.lbl_account_email = tk.Label(left_header, text="", fg="#aaaaaa", bg="#1a1a1a", font=("Arial", 9))

self.lbl_account_email.pack(anchor="w")

self.btn_menu = tk.Button(self.header, text="☰", fg="white", bg="#1a1a1a", font=("Arial", 18), bd=0, command=self.open_menu_modal)

self.btn_menu.pack(side="right")

self.notes_container = tk.Frame(self.main_frame, bg="#1a1a1a")

self.notes_container.pack(fill="both", expand=True, padx=10, pady=10)

# Оранжевий плюсик

self.btn_plus = tk.Button(self.main_frame, text="+", bg="#ff8c00", fg="white", font=("Arial", 24, "bold"), bd=0, command=self.open_create_note_modal)

self.btn_plus.place(relx=0.85, rely=0.9, anchor="center", width=55, height=55)

def show_login_screen(self):

self.main_frame.pack_forget()

self.login_frame.pack(fill="both", expand=True)

def show_main_screen(self):

self.login_frame.pack_forget()

self.main_frame.pack(fill="both", expand=True)

if self.account:

self.lbl_account_email.configure(text=self.account)

self.render_notes()

# Вікно Google-акаунта

def open_google_modal(self):

modal = tk.Toplevel(self.root)

modal.configure(bg="#ffffff")

modal.geometry("300x200")

modal.grab_set()

tk.Label(modal, text=self.t("choose_acc"), bg="#ffffff", fg="#000000", font=("Arial", 12, "bold")).pack(pady=15)

for acc in ["[email protected]", "[email protected]"]:

btn = tk.Button(modal, text=acc, bg="#f1f1f1", fg="#000000", font=("Arial", 10), bd=0, pady=6, command=lambda a=acc: self.select_account(a, modal))

btn.pack(fill="x", padx=20, pady=5)

def select_account(self, acc, modal):

self.account = acc

self.save_data()

modal.destroy()

self.show_main_screen()

# Жовте меню

def open_menu_modal(self):

modal = tk.Toplevel(self.root)

modal.configure(bg="#ffeb3b")

modal.geometry("280x320")

modal.grab_set()

tk.Label(modal, text=self.t("menu"), bg="#ffeb3b", fg="#000000", font=("Arial", 16, "bold")).pack(pady=15)

btn_logout = tk.Button(modal, text=self.t("logout"), bg="#757575", fg="white", font=("Arial", 11), bd=0, pady=8, command=lambda: self.logout(False, modal))

btn_logout.pack(fill="x", padx=25, pady=5)

btn_logout_save = tk.Button(modal, text=self.t("logout_save"), bg="#757575", fg="white", font=("Arial", 11), bd=0, pady=8, command=lambda: self.logout(True, modal))

btn_logout_save.pack(fill="x", padx=25, pady=5)

self.btn_lang = tk.Button(modal, text=self.t("lang_btn"), bg="#757575", fg="white", font=("Arial", 11), bd=0, pady=8, command=self.toggle_language)

self.btn_lang.pack(fill="x", padx=25, pady=5)

btn_back = tk.Button(modal, text=self.t("back"), bg="#9e9e9e", fg="white", font=("Arial", 10, "bold"), bd=0, pady=6, command=modal.destroy)

btn_back.pack(pady=15)

def toggle_language(self):

self.lang = "en" if self.lang == "uk" else "uk"

self.save_data()

self.btn_lang.configure(text=self.t("lang_btn"))

self.lbl_title.configure(text=self.t("title"))

self.btn_google.configure(text=self.t("login_btn"))

self.lbl_header.configure(text=self.t("title"))

self.render_notes()

def logout(self, keep_logged, modal):

modal.destroy()

if not keep_logged:

self.account = None

self.save_data()

self.show_login_screen()

# Зелене вікно створення нотатки

def open_create_note_modal(self):

modal = tk.Toplevel(self.root)

modal.configure(bg="#2e7d32")

modal.geometry("350x560")

modal.grab_set()

tk.Label(modal, text=self.t("create_title"), bg="#2e7d32", fg="white", font=("Arial", 14, "bold")).pack(pady=10)

txt_input = tk.Text(modal, bg="#1a1a1a", fg="white", font=("Arial", 11), bd=0, insertbackground="white")

txt_input.pack(fill="both", expand=True, padx=15, py=5)

lbl_char = tk.Label(modal, text="Поле: (0/300 000 сим)", bg="#2e7d32", fg="#cccccc", font=("Arial", 9))

lbl_char.pack(anchor="e", padx=15)

def on_type(event):

count = len(txt_input.get("1.0", "end-1c"))

lbl_char.configure(text=f"Поле: ({count}/300 000 сим)")

txt_input.bind("<KeyRelease>", on_type)

# Час

time_frame = tk.Frame(modal, bg="#1e4620")

time_frame.pack(fill="x", padx=15, pady=8)

tk.Label(time_frame, text=self.t("time_label"), bg="#1e4620", fg="white", font=("Arial", 11)).pack()

self.current_hour = 0

self.current_minute = 0

selectors_frame = tk.Frame(time_frame, bg="#1e4620")

selectors_frame.pack(pady=5)

btn_hour = tk.Button(selectors_frame, text="00", bg="#121212", fg="white", font=("Arial", 12, "bold"), bd=1, command=lambda: self.inc_hour(btn_hour))

btn_hour.pack(side="left", padx=10)

tk.Label(selectors_frame, text=":", bg="#1e4620", fg="white", font=("Arial", 14, "bold")).pack(side="left")

btn_min = tk.Button(selectors_frame, text="00", bg="#121212", fg="white", font=("Arial", 12, "bold"), bd=1, command=lambda: self.inc_min(btn_min))

btn_min.pack(side="left", padx=10)

# Велика кнопка ЗБЕРЕГТИ НОТАТКУ знизу + Назад

btns_frame = tk.Frame(modal, bg="#2e7d32")

btns_frame.pack(fill="x", padx=15, pady=10)

btn_save = tk.Button(btns_frame, text=self.t("save"), bg="#1b5e20", fg="white", font=("Arial", 11, "bold"), bd=0, pady=8, command=lambda: self.save_note(txt_input.get("1.0", "end-1c"), modal))

btn_save.pack(fill="x", pady=5)

btn_back = tk.Button(btns_frame, text=self.t("back"), bg="#9e9e9e", fg="white", font=("Arial", 10, "bold"), bd=0, pady=6, command=modal.destroy)

btn_back.pack(fill="x")

def inc_hour(self, btn):

self.current_hour = (self.current_hour + 1) % 24

btn.configure(text=f"{self.current_hour:02d}")

def inc_min(self, btn):

self.current_minute = (self.current_minute + 1) % 60

btn.configure(text=f"{self.current_minute:02d}")

def save_note(self, text, modal):

text = text.strip()

if not text:

return

time_str = f"{self.current_hour:02d}:{self.current_minute:02d}"

self.notes.append({"text": text, "time": time_str})

self.save_data()

modal.destroy()

self.render_notes()

def delete_note(self, index):

self.notes.pop(index)

self.save_data()

self.render_notes()

def render_notes(self):

for child in self.notes_container.winfo_children():

child.destroy()

if not self.notes:

lbl_empty = tk.Label(self.notes_container, text=self.t("no_notes"), fg="white", bg="#1a1a1a", font=("Arial", 16, "bold"))

lbl_empty.pack(expand=True)

return

for idx, note in enumerate(self.notes):

card = tk.Frame(self.notes_container, bg="#242424", bd=0)

card.pack(fill="x", py=4, px=5)

# Оранжева смужка зліва

strip = tk.Frame(card, bg="#ff8c00", width=4)

strip.pack(side="left", fill="y")

info = tk.Frame(card, bg="#242424")

info.pack(side="left", fill="x", expand=True, px=8, py=5)

lbl_txt = tk.Label(info, text=note["text"].split("\n")[0][:30], fg="white", bg="#242424", font=("Arial", 11), anchor="w")

lbl_txt.pack(fill="x")

lbl_time = tk.Label(info, text=f"Час: {note['time']}", fg="#aaaaaa", bg="#242424", font=("Arial", 9), anchor="w")

lbl_time.pack(fill="x")

# Червона мусорка

btn_del = tk.Button(card, text="🗑️", bg="#d32f2f", fg="white", font=("Arial", 10), bd=0, command=lambda i=idx: self.delete_note(i))

btn_del.pack(side="right", padx=8, py=5)

if name == "__main__":

root = tk.Tk()

app = NotesApp(root)

root.mainloop()




Готова програма•

Інші продукти в категорії «Інше»

Ми використовуємо cookie

Частина cookie потрібна, щоб працювали вхід, кошик, оплата й мова. Аналітичні та маркетингові вмикаємо лише з вашої згоди — вони показують, що працює, і допомагають авторам вимірювати рекламу. Докладніше — у Політиці конфіденційності.