ZephyrNote Python GUI

👤 Sharing: AI
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import json
import random

class ZephyrNoteApp:
    def __init__(self, root):
        self.root = root
        self.root.title("ZephyrNote")
        self.root.geometry("800x600")

        self.current_file = None
        self.settings = {"font": "Arial", "font_size": 12, "theme": "light"}

        # UI Elements
        self.create_menu()
        self.create_text_area()
        self.create_status_bar()
        self.load_settings()
        self.apply_theme()


    def create_menu(self):
        menubar = tk.Menu(self.root)

        # File Menu
        file_menu = tk.Menu(menubar, tearoff=0)
        file_menu.add_command(label="New", command=self.new_file)
        file_menu.add_command(label="Open", command=self.open_file)
        file_menu.add_command(label="Save", command=self.save_file)
        file_menu.add_command(label="Save As", command=self.save_file_as)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=self.root.quit)
        menubar.add_cascade(label="File", menu=file_menu)

        # Edit Menu
        edit_menu = tk.Menu(menubar, tearoff=0)
        edit_menu.add_command(label="Cut", command=lambda: self.text_area.event_generate("<<Cut>>"))
        edit_menu.add_command(label="Copy", command=lambda: self.text_area.event_generate("<<Copy>>"))
        edit_menu.add_command(label="Paste", command=lambda: self.text_area.event_generate("<<Paste>>"))
        edit_menu.add_command(label="Select All", command=lambda: self.text_area.tag_add("sel", "1.0", tk.END))
        menubar.add_cascade(label="Edit", menu=edit_menu)

        #Settings Menu
        settings_menu = tk.Menu(menubar, tearoff=0)
        settings_menu.add_command(label="Font", command=self.open_font_settings)
        settings_menu.add_command(label="Theme", command=self.open_theme_settings)
        menubar.add_cascade(label="Settings", menu=settings_menu)

        #Help Menu
        help_menu = tk.Menu(menubar, tearoff=0)
        help_menu.add_command(label="About", command=self.show_about)
        menubar.add_cascade(label="Help", menu=help_menu)

        self.root.config(menu=menubar)

    def create_text_area(self):
        self.text_area = tk.Text(self.root, wrap=tk.WORD, undo=True, font=(self.settings["font"], self.settings["font_size"]))
        self.text_area.pack(fill=tk.BOTH, expand=True)
        self.text_area.bind('<KeyRelease>', self.update_status_bar)

    def create_status_bar(self):
        self.status_bar = ttk.Frame(self.root, height=20)
        self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)

        self.line_col_label = ttk.Label(self.status_bar, text="Line: 1, Column: 1")
        self.line_col_label.pack(side=tk.LEFT, padx=5)

        self.word_count_label = ttk.Label(self.status_bar, text="Words: 0, Characters: 0")
        self.word_count_label.pack(side=tk.RIGHT, padx=5)
        self.update_status_bar()

    def update_status_bar(self, event=None):
        line, column = self.text_area.index(tk.INSERT).split('.')
        self.line_col_label.config(text=f"Line: {int(line) + 1}, Column: {int(column) + 1}")
        text = self.text_area.get("1.0", tk.END)
        words = len(text.split())
        characters = len(text)
        self.word_count_label.config(text=f"Words: {words}, Characters: {characters}")

    def new_file(self):
        self.text_area.delete("1.0", tk.END)
        self.current_file = None
        self.root.title("ZephyrNote")

    def open_file(self):
        file_path = filedialog.askopenfilename(defaultextension=".txt",
                                           filetypes=[("Text Files", "*.txt"),
                                                      ("All Files", "*")])
        if file_path:
            try:
                with open(file_path, "r") as file:
                    content = file.read()
                    self.text_area.delete("1.0", tk.END)
                    self.text_area.insert("1.0", content)
                self.current_file = file_path
                self.root.title(f"ZephyrNote - {file_path}")
            except Exception as e:
                messagebox.showerror("Error", f"Could not open file: {e}")

    def save_file(self):
        if self.current_file:
            try:
                content = self.text_area.get("1.0", tk.END)
                with open(self.current_file, "w") as file:
                    file.write(content)
                messagebox.showinfo("Save", "File saved successfully!")
            except Exception as e:
                messagebox.showerror("Error", f"Could not save file: {e}")
        else:
            self.save_file_as()

    def save_file_as(self):
        file_path = filedialog.asksaveasfilename(defaultextension=".txt",
                                              filetypes=[("Text Files", "*.txt"),
                                                         ("All Files", "*")])
        if file_path:
            try:
                content = self.text_area.get("1.0", tk.END)
                with open(file_path, "w") as file:
                    file.write(content)
                self.current_file = file_path
                self.root.title(f"ZephyrNote - {file_path}")
                messagebox.showinfo("Save", "File saved successfully!")
            except Exception as e:
                messagebox.showerror("Error", f"Could not save file: {e}")

    def open_font_settings(self):
        font_settings_window = tk.Toplevel(self.root)
        font_settings_window.title("Font Settings")

        font_label = ttk.Label(font_settings_window, text="Font:")
        font_label.grid(row=0, column=0, padx=5, pady=5)

        font_entry = ttk.Entry(font_settings_window)
        font_entry.grid(row=0, column=1, padx=5, pady=5)
        font_entry.insert(0, self.settings["font"])

        font_size_label = ttk.Label(font_settings_window, text="Font Size:")
        font_size_label.grid(row=1, column=0, padx=5, pady=5)

        font_size_spinbox = tk.Spinbox(font_settings_window, from_=8, to=48)
        font_size_spinbox.grid(row=1, column=1, padx=5, pady=5)
        font_size_spinbox.delete(0,"end")
        font_size_spinbox.insert(0, self.settings["font_size"])

        def apply_font_settings():
            font = font_entry.get()
            font_size = int(font_size_spinbox.get())
            self.settings["font"] = font
            self.settings["font_size"] = font_size
            self.text_area.config(font=(font, font_size))
            self.save_settings()
            font_settings_window.destroy()

        apply_button = ttk.Button(font_settings_window, text="Apply", command=apply_font_settings)
        apply_button.grid(row=2, column=0, columnspan=2, padx=5, pady=5)

    def open_theme_settings(self):
        theme_settings_window = tk.Toplevel(self.root)
        theme_settings_window.title("Theme Settings")

        theme_label = ttk.Label(theme_settings_window, text="Theme:")
        theme_label.grid(row=0, column=0, padx=5, pady=5)

        theme_combobox = ttk.Combobox(theme_settings_window, values=["light", "dark", "custom"])
        theme_combobox.grid(row=0, column=1, padx=5, pady=5)
        theme_combobox.set(self.settings["theme"])

        def apply_theme_settings():
            theme = theme_combobox.get()
            self.settings["theme"] = theme
            self.apply_theme()
            self.save_settings()
            theme_settings_window.destroy()

        apply_button = ttk.Button(theme_settings_window, text="Apply", command=apply_theme_settings)
        apply_button.grid(row=1, column=0, columnspan=2, padx=5, pady=5)


    def apply_theme(self):
        theme = self.settings["theme"]
        if theme == "light":
            bg_color = "white"
            fg_color = "black"
        elif theme == "dark":
            bg_color = "#333333"
            fg_color = "white"
        elif theme == "custom":
            # TODO: Implement custom theme selection
            bg_color = "#444444"
            fg_color = "yellow"
        else:
            bg_color = "white"
            fg_color = "black"

        self.root.configure(bg=bg_color)
        self.text_area.configure(bg=bg_color, fg=fg_color, insertbackground=fg_color)
        self.status_bar.configure(bg=bg_color)
        self.line_col_label.configure(background=bg_color, foreground=fg_color)
        self.word_count_label.configure(background=bg_color, foreground=fg_color)

    def show_about(self):
        messagebox.showinfo("About ZephyrNote", "ZephyrNote is a simple text editor created with Python and Tkinter.")

    def save_settings(self):
        try:
            with open("settings.json", "w") as f:
                json.dump(self.settings, f)
        except Exception as e:
            messagebox.showerror("Error", f"Could not save settings: {e}")

    def load_settings(self):
        try:
            with open("settings.json", "r") as f:
                self.settings = json.load(f)
        except FileNotFoundError:
            pass # Use default settings
        except Exception as e:
            messagebox.showerror("Error", f"Could not load settings: {e}")


if __name__ == "__main__":
    root = tk.Tk()
    app = ZephyrNoteApp(root)
    root.mainloop()
👁️ Viewed: 79

Comments