/
SaKob
/
Random_3
Обзор
Документация
Войти
/
SaKob
/
Random_3
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
main.py
224 строки
10 KB
SaKob
create: README.md, main.py, quotes_history.json
05 май 2026, 13:54
Верифицирован
05 май 2026, 13:54
526ee70
Код
Авторство
О чём код?
import tkinter as tk from tkinter import ttk, messagebox import random import json import os from datetime import datetime # ---------- Данные ---------- PREdefined_QUOTES = [ {"text": "Жизнь — это то, что с тобой происходит, пока ты строишь планы.", "author": "Джон Леннон", "topic": "жизнь"}, {"text": "Будь собой, прочие роли уже заняты.", "author": "Оскар Уайльд", "topic": "индивидуальность"}, {"text": "Ты никогда не пересечёшь океан, если не наберёшься смелости потерять берег из виду.", "author": "Христофор Колумб", "topic": "смелость"}, {"text": "Не важно, как медленно ты идёшь, главное — не останавливаться.", "author": "Конфуций", "topic": "мотивация"}, {"text": "Логика может привести тебя от А до Б, а воображение — куда угодно.", "author": "Альберт Эйнштейн", "topic": "воображение"}, {"text": "Сложнее всего начать действовать, остальное зависит от упорства.", "author": "Амелия Эрхарт", "topic": "действие"}, {"text": "Люби то, что делаешь, и делай то, что любишь.", "author": "Стив Джобс", "topic": "работа"} ] # Файл для хранения истории HISTORY_FILE = "quotes_history.json" class QuoteApp: def __init__(self, root): self.root = root self.root.title("Random Quote Generator") self.root.geometry("650x600") self.root.resizable(True, True) # История цитат self.history = self.load_history() self.filtered_history = [] # Интерфейс self.create_widgets() self.refresh_history_display() # ---------- Работа с JSON ---------- def load_history(self): if os.path.exists(HISTORY_FILE): try: with open(HISTORY_FILE, "r", encoding="utf-8") as f: return json.load(f) except: return [] return [] def save_history(self): with open(HISTORY_FILE, "w", encoding="utf-8") as f: json.dump(self.history, f, ensure_ascii=False, indent=2) # ---------- Создание интерфейса ---------- def create_widgets(self): # Основной фрейм main_frame = ttk.Frame(self.root, padding="10") main_frame.pack(fill="both", expand=True) # --- Блок генерации цитаты --- ttk.Label(main_frame, text="🎲 Генератор случайных цитат", font=("Arial", 14, "bold")).pack(pady=5) self.generate_btn = ttk.Button(main_frame, text="✨ Сгенерировать цитату ✨", command=self.generate_quote) self.generate_btn.pack(pady=10) # Поле для отображения цитаты self.quote_frame = ttk.LabelFrame(main_frame, text="Текущая цитата", padding="10") self.quote_frame.pack(fill="x", pady=5) self.quote_text = tk.Text(self.quote_frame, height=4, wrap="word", font=("Arial", 11)) self.quote_text.pack(fill="x") self.quote_text.config(state="disabled") # --- Блок фильтрации --- filter_frame = ttk.LabelFrame(main_frame, text="Фильтр", padding="10") filter_frame.pack(fill="x", pady=5) ttk.Label(filter_frame, text="Автор:").grid(row=0, column=0, padx=5) self.author_filter = ttk.Combobox(filter_frame, values=self.get_all_authors(), width=20) self.author_filter.grid(row=0, column=1, padx=5) self.author_filter.set("Все") ttk.Label(filter_frame, text="Тема:").grid(row=0, column=2, padx=5) self.topic_filter = ttk.Combobox(filter_frame, values=self.get_all_topics(), width=20) self.topic_filter.grid(row=0, column=3, padx=5) self.topic_filter.set("Все") self.filter_btn = ttk.Button(filter_frame, text="🔍 Применить фильтр", command=self.apply_filter) self.filter_btn.grid(row=0, column=4, padx=10) # --- Блок истории --- history_frame = ttk.LabelFrame(main_frame, text="История цитат", padding="10") history_frame.pack(fill="both", expand=True, pady=5) # Создаём список для истории с прокруткой scrollbar = ttk.Scrollbar(history_frame) scrollbar.pack(side="right", fill="y") self.history_listbox = tk.Listbox(history_frame, yscrollcommand=scrollbar.set, font=("Arial", 9)) self.history_listbox.pack(fill="both", expand=True) scrollbar.config(command=self.history_listbox.yview) # --- Блок добавления новой цитаты --- add_frame = ttk.LabelFrame(main_frame, text="Добавить новую цитату", padding="10") add_frame.pack(fill="x", pady=5) ttk.Label(add_frame, text="Текст:").grid(row=0, column=0, sticky="w", pady=2) self.new_text = tk.Text(add_frame, height=2, width=50) self.new_text.grid(row=0, column=1, columnspan=3, pady=2) ttk.Label(add_frame, text="Автор:").grid(row=1, column=0, sticky="w", pady=2) self.new_author = ttk.Entry(add_frame, width=30) self.new_author.grid(row=1, column=1, pady=2) ttk.Label(add_frame, text="Тема:").grid(row=1, column=2, sticky="w", pady=2) self.new_topic = ttk.Entry(add_frame, width=30) self.new_topic.grid(row=1, column=3, pady=2) self.add_btn = ttk.Button(add_frame, text="➕ Добавить цитату", command=self.add_quote) self.add_btn.grid(row=2, column=0, columnspan=4, pady=5) # ---------- Вспомогательные методы ---------- def get_all_authors(self): authors = set() for q in PREdefined_QUOTES: authors.add(q["author"]) for q in self.history: if "author" in q: authors.add(q["author"]) return ["Все"] + sorted(authors) def get_all_topics(self): topics = set() for q in PREdefined_QUOTES: topics.add(q["topic"]) for q in self.history: if "topic" in q: topics.add(q["topic"]) return ["Все"] + sorted(topics) def refresh_filters(self): self.author_filter["values"] = self.get_all_authors() self.topic_filter["values"] = self.get_all_topics() def generate_quote(self): """Выбирает случайную цитату из объединённого списка""" all_quotes = PREdefined_QUOTES + self.history if not all_quotes: messagebox.showinfo("Нет цитат", "Нет доступных цитат. Добавьте свои.") return quote = random.choice(all_quotes) self.display_quote(quote) # Сохраняем в историю с временной меткой quote_with_time = quote.copy() quote_with_time["timestamp"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.history.append(quote_with_time) self.save_history() self.refresh_history_display() self.refresh_filters() def display_quote(self, quote): self.quote_text.config(state="normal") self.quote_text.delete(1.0, tk.END) self.quote_text.insert(tk.END, f"«{quote['text']}»\n\n— {quote['author']} (тема: {quote['topic']})") self.quote_text.config(state="disabled") def add_quote(self): """Добавляет новую цитату с проверкой на пустые строки""" text = self.new_text.get(1.0, tk.END).strip() author = self.new_author.get().strip() topic = self.new_topic.get().strip() if not text or not author or not topic: messagebox.showerror("Ошибка", "Все поля должны быть заполнены!") return new_quote = {"text": text, "author": author, "topic": topic} self.history.append(new_quote) self.save_history() # Очищаем поля self.new_text.delete(1.0, tk.END) self.new_author.delete(0, tk.END) self.new_topic.delete(0, tk.END) self.refresh_history_display() self.refresh_filters() messagebox.showinfo("Успех", "Цитата добавлена!") def apply_filter(self): """Фильтрует историю по автору и теме""" author = self.author_filter.get() topic = self.topic_filter.get() filtered = [] for q in self.history: match_author = (author == "Все" or q.get("author") == author) match_topic = (topic == "Все" or q.get("topic") == topic) if match_author and match_topic: filtered.append(q) self.filtered_history = filtered self.refresh_history_display(use_filter=True) def refresh_history_display(self, use_filter=False): """Обновляет отображение списка истории""" self.history_listbox.delete(0, tk.END) items = self.filtered_history if use_filter else self.history if not items: self.history_listbox.insert(tk.END, "История пуста...") return for q in items: timestamp = q.get("timestamp", "нет даты") text = q.get("text", "")[:50] + "..." if len(q.get("text", "")) > 50 else q.get("text", "") display = f"[{timestamp}] {q.get('author', '?')}: «{text}»" self.history_listbox.insert(tk.END, display) # ---------- Запуск приложения ---------- if __name__ == "__main__": root = tk.Tk() app = QuoteApp(root) root.mainloop()