Создаем красивое приложение заметок на tkinter

Современный GUI с красивым дизайном и полной функциональностью

Время чтения: 25 минут
Python, tkinter, GUI, заметки

Введение в tkinter

tkinter — это стандартная библиотека Python для создания графических пользовательских интерфейсов (GUI). Она входит в состав Python и не требует дополнительной установки, что делает её идеальным выбором для начинающих разработчиков.

Преимущества tkinter:
  • Встроенная в Python — не требует установки
  • Кроссплатформенность — работает на Windows, macOS, Linux
  • Простота изучения — понятный API
  • Богатая документация и примеры
  • Возможность создания современных интерфейсов

Что мы создадим

В этой статье мы создадим стильное приложение для заметок со следующими возможностями:

  • Создание, редактирование и удаление заметок
  • Современный и красивый интерфейс
  • Сохранение заметок в файл
  • Поиск по заметкам
  • Категории и теги
  • Автосохранение

Планирование приложения

Перед началом разработки важно продумать структуру приложения и его интерфейс. Это поможет избежать множественных переделок в процессе разработки.

Структура приложения

Подготовьте модульную структуру: вынесите создание виджетов, обработчики событий и логику сохранения данных в отдельные методы/классы. Это упростит сопровождение и развитие приложения.

Основные компоненты

  • Главное окно — контейнер для всех элементов
  • Панель инструментов — кнопки для создания, удаления, поиска
  • Список заметок — отображение всех заметок
  • Область редактирования — для создания и редактирования заметок
  • Строка состояния — информация о количестве заметок

Базовая настройка окна

Начнем с создания базового окна приложения и настройки его основных параметров.

Создание главного окна

notes_app.py
import tkinter as tk from tkinter import ttk, messagebox import json from datetime import datetime class NotesApp: def __init__(self, root): self.root = root self.root.title("📝 Мои заметки") self.root.geometry("800x600") self.root.minsize(600, 400) # Настройка стиля self.setup_styles() # Инициализация данных self.notes = [] self.current_note = None # Создание интерфейса self.create_widgets() # Загрузка заметок self.load_notes() def setup_styles(self): """Настройка стилей для красивого интерфейса""" style = ttk.Style() style.theme_use('clam') # Настройка цветов style.configure('Main.TFrame', background='#f8fafc') style.configure('Toolbar.TFrame', background='#8b5cf6') style.configure('Toolbar.TButton', background='#7c3aed', foreground='white', borderwidth=0, focuscolor='none') # Настройка кнопок style.map('Toolbar.TButton', background=[('active', '#6d28d9')], foreground=[('active', 'white')]) def create_widgets(self): """Создание элементов интерфейса""" # Главный контейнер self.main_frame = ttk.Frame(self.root, style='Main.TFrame') self.main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) # Панель инструментов self.create_toolbar() # Основная область self.create_main_area() # Строка состояния self.create_status_bar() if __name__ == "__main__": root = tk.Tk() app = NotesApp(root) root.mainloop()
Отлично! Мы создали базовую структуру приложения. Теперь у нас есть главное окно с настройкой стилей.

Создание красивого дизайна

Теперь добавим красивые элементы интерфейса и настроим их стили для создания современного вида.

Панель инструментов

toolbar.py
def create_toolbar(self): """Создание панели инструментов""" toolbar = ttk.Frame(self.main_frame, style='Toolbar.TFrame') toolbar.pack(fill=tk.X, pady=(0, 10)) # Кнопки ttk.Button(toolbar, text="➕ Новая заметка", style='Toolbar.TButton', command=self.new_note).pack(side=tk.LEFT, padx=5, pady=5) ttk.Button(toolbar, text="💾 Сохранить", style='Toolbar.TButton', command=self.save_note).pack(side=tk.LEFT, padx=5, pady=5) ttk.Button(toolbar, text="🗑️ Удалить", style='Toolbar.TButton', command=self.delete_note).pack(side=tk.LEFT, padx=5, pady=5) # Поиск search_frame = ttk.Frame(toolbar) search_frame.pack(side=tk.RIGHT, padx=10, pady=5) ttk.Label(search_frame, text="🔍", background='#8b5cf6', foreground='white').pack(side=tk.LEFT) self.search_var = tk.StringVar() self.search_var.trace('w', self.search_notes) search_entry = ttk.Entry(search_frame, textvariable=self.search_var, width=20) search_entry.pack(side=tk.LEFT, padx=5) def create_main_area(self): """Создание основной области приложения""" # Контейнер для разделения на две части paned_window = ttk.PanedWindow(self.main_frame, orient=tk.HORIZONTAL) paned_window.pack(fill=tk.BOTH, expand=True) # Левая панель - список заметок self.create_notes_list(paned_window) # Правая панель - редактирование self.create_edit_area(paned_window) def create_notes_list(self, parent): """Создание списка заметок""" list_frame = ttk.Frame(parent) parent.add(list_frame, weight=1) # Заголовок ttk.Label(list_frame, text="📋 Список заметок", font=('Arial', 12, 'bold')).pack(pady=10) # Список заметок self.notes_listbox = tk.Listbox(list_frame, font=('Arial', 10), selectmode=tk.SINGLE, bg='#f8fafc', fg='#1f2937', selectbackground='#8b5cf6', selectforeground='white', borderwidth=1, relief=tk.SOLID) self.notes_listbox.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) self.notes_listbox.bind('<>', self.on_note_select) def create_edit_area(self, parent): """Создание области редактирования""" edit_frame = ttk.Frame(parent) parent.add(edit_frame, weight=2) # Заголовок ttk.Label(edit_frame, text="✏️ Редактирование", font=('Arial', 12, 'bold')).pack(pady=10) # Поле для заголовка title_frame = ttk.Frame(edit_frame) title_frame.pack(fill=tk.X, padx=10, pady=5) ttk.Label(title_frame, text="Заголовок:").pack(anchor=tk.W) self.title_entry = ttk.Entry(title_frame, font=('Arial', 11)) self.title_entry.pack(fill=tk.X, pady=2) # Поле для текста заметки text_frame = ttk.Frame(edit_frame) text_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) ttk.Label(text_frame, text="Текст заметки:").pack(anchor=tk.W) # Создаем текстовое поле с прокруткой text_container = ttk.Frame(text_frame) text_container.pack(fill=tk.BOTH, expand=True, pady=2) self.text_widget = tk.Text(text_container, font=('Arial', 10), wrap=tk.WORD, bg='white', fg='#1f2937', insertbackground='#8b5cf6', selectbackground='#e9d5ff', borderwidth=1, relief=tk.SOLID) scrollbar = ttk.Scrollbar(text_container, orient=tk.VERTICAL, command=self.text_widget.yview) self.text_widget.configure(yscrollcommand=scrollbar.set) self.text_widget.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) def create_status_bar(self): """Создание строки состояния""" self.status_bar = ttk.Label(self.main_frame, text="Готово", relief=tk.SUNKEN, anchor=tk.W) self.status_bar.pack(fill=tk.X, pady=(10, 0)) def new_note(self): """Создание новой заметки""" self.current_note = None self.title_entry.delete(0, tk.END) self.text_widget.delete(1.0, tk.END) self.status_bar.config(text="Создание новой заметки...") def save_note(self): """Сохранение заметки""" title = self.title_entry.get().strip() text = self.text_widget.get(1.0, tk.END).strip() if not title: messagebox.showwarning("Предупреждение", "Введите заголовок заметки!") return if self.current_note is None: # Создаем новую заметку note = { 'id': len(self.notes) + 1, 'title': title, 'text': text, 'created': datetime.now().isoformat(), 'modified': datetime.now().isoformat() } self.notes.append(note) else: # Обновляем существующую заметку self.notes[self.current_note]['title'] = title self.notes[self.current_note]['text'] = text self.notes[self.current_note]['modified'] = datetime.now().isoformat() self.update_notes_list() self.save_notes_to_file() self.status_bar.config(text=f"Заметка '{title}' сохранена") def delete_note(self): """Удаление заметки""" if self.current_note is None: messagebox.showinfo("Информация", "Выберите заметку для удаления!") return if messagebox.askyesno("Подтверждение", "Удалить выбранную заметку?"): del self.notes[self.current_note] self.current_note = None self.title_entry.delete(0, tk.END) self.text_widget.delete(1.0, tk.END) self.update_notes_list() self.save_notes_to_file() self.status_bar.config(text="Заметка удалена") def on_note_select(self, event): """Обработка выбора заметки в списке""" selection = self.notes_listbox.curselection() if selection: self.current_note = selection[0] note = self.notes[self.current_note] self.title_entry.delete(0, tk.END) self.title_entry.insert(0, note['title']) self.text_widget.delete(1.0, tk.END) self.text_widget.insert(1.0, note['text']) self.status_bar.config(text=f"Заметка '{note['title']}' загружена") def update_notes_list(self): """Обновление списка заметок""" self.notes_listbox.delete(0, tk.END) for note in self.notes: self.notes_listbox.insert(tk.END, note['title']) def search_notes(self, *args): """Поиск по заметкам""" search_term = self.search_var.get().lower() self.notes_listbox.delete(0, tk.END) for note in self.notes: if (search_term in note['title'].lower() or search_term in note['text'].lower()): self.notes_listbox.insert(tk.END, note['title']) def load_notes(self): """Загрузка заметок из файла""" try: with open('notes.json', 'r', encoding='utf-8') as f: self.notes = json.load(f) self.update_notes_list() self.status_bar.config(text=f"Загружено {len(self.notes)} заметок") except FileNotFoundError: self.status_bar.config(text="Файл заметок не найден, создан новый") def save_notes_to_file(self): """Сохранение заметок в файл""" try: with open('notes.json', 'w', encoding='utf-8') as f: json.dump(self.notes, f, ensure_ascii=False, indent=2) except Exception as e: messagebox.showerror("Ошибка", f"Не удалось сохранить заметки: {e}") if __name__ == "__main__": root = tk.Tk() app = NotesApp(root) root.mainloop()
Отлично! Мы создали полнофункциональное приложение заметок с красивым интерфейсом!

Готовое приложение

Теперь у нас есть полностью функциональное приложение заметок со следующими возможностями:

Функциональность

  • ✅ Создание новых заметок
  • ✅ Редактирование существующих заметок
  • ✅ Удаление заметок
  • ✅ Поиск по заголовку и содержимому
  • ✅ Автоматическое сохранение в JSON файл
  • ✅ Загрузка заметок при запуске
  • ✅ Современный и красивый интерфейс

Как запустить приложение

  1. Сохраните весь код в файл notes_app.py
  2. Откройте командную строку в папке с файлом
  3. Выполните команду: python notes_app.py
  4. Наслаждайтесь вашим приложением!
Особенности дизайна:
  • Градиентная панель инструментов в фиолетовых тонах
  • Современные кнопки с иконками
  • Разделение окна на две панели
  • Красивое оформление списка заметок
  • Стильное текстовое поле для редактирования
  • Информативная строка состояния

Дальнейшее развитие

Теперь, когда у вас есть базовое приложение, вы можете добавить дополнительные функции:

Возможные улучшения

  • Категории и теги — группировка заметок по темам
  • Форматирование текста — жирный, курсив, подчеркивание
  • Вложения файлов — добавление изображений и документов
  • Экспорт заметок — сохранение в PDF, HTML, TXT
  • Настройки приложения — выбор темы, шрифтов
  • Резервное копирование — автоматическое создание бэкапов
  • Синхронизация — работа с облачными сервисами

Изучение других GUI библиотек

После освоения tkinter вы можете изучить другие библиотеки:

  • PyQt/PySide — мощные и современные GUI фреймворки
  • Kivy — для создания мобильных и десктопных приложений
  • Dear PyGui — быстрая библиотека для создания интерфейсов
  • CustomTkinter — современная версия tkinter с красивыми виджетами
Советы для дальнейшего изучения:
  • Изучите документацию tkinter
  • Создавайте собственные виджеты
  • Экспериментируйте с различными темами
  • Изучите паттерны проектирования для GUI
  • Создавайте более сложные приложения
"Лучший способ изучить программирование — это создавать реальные проекты, которые решают ваши задачи."

Поздравляем! Вы создали свое первое GUI приложение на Python!

Продолжайте обучение бесплатно

Хотите системно прокачать Python? Пройдите наш бесплатный курс: от основ до практики.