Bienvenidos a infinito python, hoy vamos a hablar sobre un proyecto que he hecho estos días, como dice el título, es un editor de texto. Abajo tenéis los enlaces para el código y para el archivo .exe
Lo primero que necesitaremos, será un editor de python con extensiones de tkinter, También, puedes usar python oficial que puedes descargar desde python.org.
Lo primero que necesitaremos, será invocar a tkinter y en el crear el menú superior.
_______________________________________________
from tkinter import * root = Tk() root.title("Mi editor") # Menú superior menubar = Menu(root) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Nuevo") filemenu.add_command(label="Abrir") filemenu.add_command(label="Guardar") filemenu.add_command(label="Guardar como") filemenu.add_separator() filemenu.add_command(label="Salir", command=root.quit) menubar.add_cascade(label="Archivo", menu=filemenu) # Caja de texto central texto = Text(root) texto.pack(fill='both', expand=1) texto.config(padx=6, pady=4, bd=0, font=("Consolas", 12)) # Menu y bucle de la aplicación root.config(menu=menubar) root.mainloop()Ahora, lo que vamos ha hacer, es crear una barra inferior que contendrá el nombre de nuestro editor de texto.
# Monitor inferior
mensaje = StringVar()
mensaje.set('Bienvenido a tu editor')
monitor = Label(root, textvar=mensaje, justify='right')
monitor.pack(side='left')
Dicho esto, ya tendremos la "imagen" de nuestro editor de texto.Ahora, ya podemos crear las definiciones y luego enlazarlas.
#Definiciones
def nuevo():
mensaje.set('Nuevo fichero')
def abrir():
mensaje.set('Nuevo fichero')
def guardar():
mensaje.set('Guardar fichero')
def guardar_como():
print("Guardar fichero como")
#Enlaces
filemenu.add_command(label="Nuevo", command=nuevo)
filemenu.add_command(label="Abrir", command=abrir)
filemenu.add_command(label="Guardar", command=guardar)
filemenu.add_command(label="Guardar como", command=guardar_como)
Antes de nada vamos a crear una variable global ruta, fuera del ámbito de las funciones.
ruta = '' # La utilizaremos para almacenar información
Comenzando por un nuevo fichero, lo que este comando hará, será dejarlo vacío y reiniciar las configuraciones.
def nuevo():
mensaje.set('Nuevo fichero')
texto.delete(1.0, END)# En flotante, el primer carácter es un salto
Ya sabemos que podemos utilizar una ventana emergente para pedirle al usuario que seleccione un fichero del disco duro, así que vamos a importar el módulo file dialog:
from tkinter import filedialog as FileDialog
Ahora tenemos que programar toda la lógica:
def abrir():
# Indicamos que la ruta es respecto a la variable global
# Debemos de forzar esta lectura global porque los comandos
# sólo son conscientes de las variables externas que son widgets
global ruta
mensaje.set('Abrir fichero')
ruta = FileDialog.askopenfilename(
initialdir='.',
filetypes=( # Es una tupla con un elemento
("Ficheros de texto", "*.txt"),
),
title="Abrir un fichero."
)
# Si la ruta es válida abrimos el contenido en lectura
if ruta != "":
fichero = open(ruta, 'r')
contenido = fichero.read()
texto.delete(1.0, 'end') # Nos aseguramos de que esté vacío
texto.insert('insert', contenido)# Le insertamos el contenido
fichero.close() # Cerramos el fichero
root.title(ruta + " - Mi editor")# Cambiamos el título
Muy bien, ya podemos abrir ficheros. Vamos a aprovechar y antes de continuar, importante que reiniciemos el título de ventana y la ruta si hacemos Nuevo. Si no lo hacemos, como mínimo la ruta, a la hora de guardar no podremos distinguir si un fichero es nuevo, o se ha abierto desde el disco duro:
def abrir(): # Indicamos que la ruta es respecto a la variable global global ruta mensaje.set('Nuevo fichero') texto.delete(1.0, END)# En flotante, el primer carácter es un salto root.title("Mi editor")# Reiniciamos el título ruta = "" # Reiniciamos la rutaARCHIVO EXE---------------------------> text_editor.exeA la hora de guardar un fichero tenemos dos opciones, o es un fichero ya existente, en ese caso en la ruta tendremos un valor, o será un fichero nuevo, una ruta vacía.En el primer caso vamos a proceder a guardar normalmente el fichero como ya sabemos:def guardar(): global ruta if ruta != "": contenido = texto.get(1.0, 'end') # Recuperamos el texto fichero = open(ruta, 'w+') # Creamos el fichero o abrimos fichero.write(contenido) # Escribimos el texto fichero.close() mensaje.set('Fichero guardado correctamente')Si lo probamos veremos que todo se guarda correctamente. Pero si guardamos un fichero y lo volvemos a abrir, curiosamente se nos va añadiendo un salto de línea al final. Para solucionarlo, o le restamos ese último carácter manualmente antes de guardar, o bien le indicamos en el propio get que lo reste:
contenido = texto.get(1.0, 'end-1c') # recuperamos el texto -1 charAhora nos falta la otra posibilidad, cuando el fichero es nuevo y tenemos que guardarlo en el disco con un nombre. Para este caso lo que vamos a hacer es llamar desde la función guardar la función guardar como, ya que ésta nos debería permitirhacer lo que necesitamos la primera vez eligiendo un nombre y un directorio:
else: guardar_como()Ya sólo nos falta crear la última opción:def guardar_como(): global ruta fichero = FileDialog.asksaveasfile(title="Guardar fichero", mode='w', defaultextension=".txt") ruta = fichero.name # El atributo name es la ruta, si está abierto if fichero is not None: contenido = texto.get(1.0, 'end-1c') # recuperamos el texto fichero = open(ruta, 'w+') # creamos el fichero o abrimos fichero.write(contenido) # escribimos el texto fichero.close() mensaje.set('Fichero guardado correctamente') else: mensaje.set('Guardado cancelado')
CÓDIGO FINAL
_____________________________________________________________________
from tkinter import * from tkinter import filedialog as FileDialog from io import open ruta = "" # La utilizaremos para almacenar la ruta del fichero def nuevo(): global ruta mensaje.set("Nuevo fichero") ruta = "" texto.delete(1.0, "end") root.title("Mi editor") def abrir(): global ruta mensaje.set("Abrir fichero") ruta = FileDialog.askopenfilename( initialdir='.', filetypes=(("Ficheros de texto", "*.txt"),), title="Abrir un fichero de texto") if ruta != "": fichero = open(ruta, 'r') contenido = fichero.read() texto.delete(1.0,'end') texto.insert('insert', contenido) fichero.close() root.title(ruta + " - Mi editor") def guardar(): mensaje.set("Guardar fichero") if ruta != "": contenido = texto.get(1.0,'end-1c') fichero = open(ruta, 'w+') fichero.write(contenido) fichero.close() mensaje.set("Fichero guardado correctamente") else: guardar_como() def guardar_como(): global ruta mensaje.set("Guardar fichero como") fichero = FileDialog.asksaveasfile(title="Guardar fichero", mode="w", defaultextension=".txt") if fichero is not None: ruta = fichero.name contenido = texto.get(1.0,'end-1c') fichero = open(ruta, 'w+') fichero.write(contenido) fichero.close() mensaje.set("Fichero guardado correctamente") else: mensaje.set("Guardado cancelado") ruta = "" # Configuración de la raíz root = Tk() root.title("Mi editor") # Menú superior menubar = Menu(root) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Nuevo", command=nuevo) filemenu.add_command(label="Abrir", command=abrir) filemenu.add_command(label="Guardar", command=guardar) filemenu.add_command(label="Guardar como", command=guardar_como) filemenu.add_separator() filemenu.add_command(label="Salir", command=root.quit) menubar.add_cascade(menu=filemenu, label="Archivo") # Caja de texto central texto = Text(root) texto.pack(fill="both", expand=1) texto.config(bd=0, padx=6, pady=4, font=("Consolas",12)) # Monitor inferior mensaje = StringVar() mensaje.set("Bienvenido a tu Editor") monitor = Label(root, textvar=mensaje, justify='left') monitor.pack(side="left") root.config(menu=menubar) # Finalmente bucle de la apliación root.mainloop()ARCHIVO PYTHON --------------------> text_editor.py
INSTRUCCIONES ARCHIVO .EXE
_________________________________________________________________________________
Debes descargar el archivo zip, extraerlo y luego abrir el archivo Wobegone_text_editor.exe
ATENCIÓN!!! NO CIERRES LA PESTAÑA QUE ES COMO UNA CONSOLA DE COMANDOS,
ES LA QUE HACE QUE EL PROGRAMA FUNCIONE SIN TENER PYTHON INSTALADO.
Muy buen código
ResponderEliminarPodrias añadir un botón para que se pueda imprimir.
Gracias por tu comentario, ya intentaremos añadir unos cuantos botones más. Este es el código básico.
EliminarNo te pierdas uno de nuestros nuevos proyectos, el generador de contraseñas seguras y el recuperador de contraseñas.
Buenas noches, me alegra saber que publicarán nuevo código, pero cuando lo harán?
EliminarAdemás,quería comentarles que tengo un blog en el que cuelgo código, ¿podría subir el código que aparece en este blog?