├── LICENSE ├── README.md └── TextEditor.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Youssef JABRI 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Text Editor - Python 2 | - Python 3.12.2 3 | - Tkinter 4 | 5 | ![image](https://github.com/youssefjabri/Text-Editor-Python/assets/118174610/f2fa1807-256b-4b4b-abd6-f0113d7ff518) 6 | -------------------------------------------------------------------------------- /TextEditor.py: -------------------------------------------------------------------------------- 1 | import tkinter as Tk 2 | from tkinter import messagebox 3 | from tkinter.filedialog import askopenfilename, asksaveasfilename 4 | 5 | def open_file(): 6 | global current_file_saved, filepath 7 | filepath = askopenfilename( 8 | filetypes=[("Text File", "*.txt"), ("All Files", "*.*")] 9 | ) 10 | if not filepath: 11 | return 12 | text_edit.delete(1.0, Tk.END) 13 | with open(filepath, 'r') as input_file: 14 | text = input_file.read() 15 | text_edit.insert(Tk.END, text) 16 | window.title(f"Text Editor - {filepath}") 17 | current_file_saved = True 18 | 19 | def save_file(event=None): 20 | global current_file_saved, filepath 21 | if not filepath: 22 | filepath = asksaveasfilename( 23 | defaultextension="txt", 24 | filetypes=[("Text File", "*.txt"), ("All Files", "*.*")] 25 | ) 26 | if not filepath: 27 | return 28 | with open(filepath, "w") as output_file: 29 | text = text_edit.get(1.0, Tk.END).strip() 30 | output_file.write(text) 31 | window.title(f"Text Editor - {filepath}") 32 | current_file_saved = True 33 | 34 | def on_text_change(event=None): 35 | global current_file_saved 36 | if text_edit.edit_modified(): 37 | if current_file_saved: 38 | window.title(f"Text Editor - {filepath or 'Untitled*'}") 39 | current_file_saved = False 40 | text_edit.edit_modified(False) 41 | 42 | def on_closing(): 43 | if not current_file_saved: 44 | response = messagebox.askyesnocancel( 45 | "Unsaved Changes", 46 | "You have unsaved changes. Do you want to save them before closing?" 47 | ) 48 | if response is None: 49 | return 50 | elif response: 51 | save_file() 52 | window.destroy() 53 | 54 | current_file_saved = True 55 | filepath = None 56 | 57 | window = Tk.Tk() 58 | window.title("Text Editor") 59 | window.rowconfigure(0, minsize=500, weight=1) 60 | window.columnconfigure(1, minsize=500, weight=1) 61 | 62 | text_edit = Tk.Text(window) 63 | fr_buttons = Tk.Frame(window, relief=Tk.RAISED, bd=1) 64 | btn_open = Tk.Button(fr_buttons, text="Open...", command=open_file) 65 | btn_save = Tk.Button(fr_buttons, text="Save...", command=save_file) 66 | 67 | btn_open.grid(row=0, column=0, sticky="ew", padx=2, pady=2) 68 | btn_save.grid(row=1, column=0, sticky="ew", padx=2) 69 | 70 | fr_buttons.grid(row=0, column=0, sticky="ns") 71 | text_edit.grid(row=0, column=1, sticky="nsew") 72 | 73 | text_edit.bind("<>", on_text_change) 74 | text_edit.bind("", save_file) 75 | window.protocol("WM_DELETE_WINDOW", on_closing) 76 | 77 | window.mainloop() 78 | --------------------------------------------------------------------------------