Construye un editor Markdown simple usando Python y Tkinter

Todos deberían conocer el editor Markdown, que es muy popular entre los programadores. Muchas personas están creando un editor de Markdown, algunos son creativos, otros son aburridos.

Antes de comenzar, expliquemos por qué la gente no quiere usar tkinter para construir el editor Markdown. Esto se debe a que no existe un método simple predeterminado para mostrar datos html de entrada de descuento. Ni siquiera hay un componente tkinter predeterminado para mostrar datos html. Simplemente puede escribir / editar rebajas, pero no hay una manera fácil de mostrar la salida en la aplicación.

Sin embargo, ahora que tenemos tk_html_widgets , puede ayudarnos a mostrar la salida html.

Pero, por supuesto, también tiene algunos problemas: la fuente es demasiado pequeña y no admite adjuntar fotos remotas.

Ahora comencemos a construir.

Comience a construir:

Primero, asegúrese de haber instalado Python 3 y Tkinter. Si no, puede descargarlo desde aquí:
python.org/downloads (Tkinter ya está incluido en Python).

Las otras cosas que necesitamos son tkhtmlview y markdown2. Puede instalarlos ejecutando pip install tkhtmlview markdown2 o pip3 install tkhtmlview markdown2 (si tiene varias versiones de Python).

Comenzaremos importando las bibliotecas necesarias.

desde tkinter import *
desde tkinter import font, filedialog
desde markdown2 import Markdown
desde tkhtmlview import HTMLLabel

En la primera línea, importamos (casi) todo desde el paquete tkinter.

En la segunda línea, importamos la fuente y el diálogo del archivo. Debe usar la fuente para establecer el estilo del campo de entrada (por ejemplo, Fuente, Tamaño de fuente) e importar el cuadro de diálogo de archivo para abrir el archivo de rebajas para editar (y / o guardar nuestro archivo de rebajas).

En la tercera línea, Markdown se importó para ayudarnos a convertir la fuente de Markdown a html y usar HTMLLabel (importado en la cuarta línea) para mostrarlo en el campo de salida.

Después de eso, crearemos una clase de marco llamada Window, que heredará de la clase Frame de skinters. Guardará nuestros campos de entrada y salida.

Ventana de clase (Frame):
    def __init __ (self, master = None):
        Frame .__ init __ (self, master)
        self.master = master
        self.myfont = font.Font (family = "Helvetica", size = 14)
        self.init_window ()

En este bloque de código, primero definimos una clase llamada Window, que hereda la clase de widget Frame de tkinter.

Ahora, en la función de inicialización, tomamos master como parámetro y lo usamos como padre del framework. En la siguiente línea, inicializamos un Frame.

A continuación, declaramos un objeto de fuente personalizado llamado self.myfont cuya familia de fuentes es Helvetica (puede elegir cualquier familia de fuentes) y el tamaño es 15, que se utilizará en nuestro campo de entrada de rebajas.

Finalmente, llamamos a la función init_window para colocar nuestra aplicación en la ubicación central.

Establecemos el parámetro de palabra clave de relleno en AMBOS, que en realidad se importa de la biblioteca tkinter. Le dice al marco que llene la ventana tanto en dirección horizontal como vertical, y el parámetro de palabra clave expandir se establece en 1 (lo que significa Verdadero), lo que nos dice que el marco es extensible. En resumen, no importa cómo estiramos el tamaño de la ventana o maximizamos el tamaño de la ventana, el marco llenará la ventana.

Para resolver este problema, colocamos el siguiente código al final del script:

root = Tk ()
root.geometry ("800x600")
app = Window (root)
app.mainloop ()

Luego, establezca la geometría de la ventana en un cuadro de 800x600, 800 es la altura de la ventana y 600 es el ancho de la ventana. En la siguiente línea, puede ver que estamos creando un objeto Window. Empujamos la variable raíz en la raíz del marco y la almacenamos en una variable llamada aplicación.

¡Lo siguiente que debe hacer es llamar a la función mainloop, que le dice a nuestra aplicación que se ejecute!

Cómo construir un editor Markdown simple usando Python y Tkinter

Pero esto es solo una ventana en blanco. Para escribir contenido en la ventana, necesitamos agregar un campo de texto en el que escribir nuestra rebaja. Para esto, usaremos el widget Text en tkinter.

    self.inputeditor = Text (self, width = "1")
    self.inputeditor.pack (fill = BOTH, expand = 1, side = LEFT)

No debe confundirse con (tres puntos), los puse allí solo para indicar que hay varias líneas de código antes de este bloque de código.

Aquí, creamos un widget de texto con un ancho de 1. No me malinterpretes, piensa que está mal: el tamaño aquí se hace usando proporciones. Cuando lo ponemos en el cuadro de salida, lo entenderá más claramente en los próximos segundos.

Luego, lo empacamos en un marco y lo hicimos extensible tanto horizontal como verticalmente.

Cuando ejecute el script, verá que el "Campo de entrada de líneas múltiples" se ha apoderado de toda la "ventana". Si comienza a escribirlo, puede notar que los caracteres son demasiado pequeños.

Construye un editor Markdown simple usando Python y Tkinter

Ya sé que este problema ocurrirá. Es por eso que te dije que crearas un objeto de fuente personalizado (self.myfont) antes. Ahora, si haces lo siguiente:

self.inputeditor = Text (self, width = "1", font = self.myfont)

(¡Aquí, le decimos al widget Texto que use una fuente personalizada en lugar de la fuente pequeña predeterminada!)

... el tamaño de fuente del campo de entrada se incrementará a 15. Ejecute el script para verificar si todo es normal.

Construye un editor Markdown simple usando Python y Tkinter

Ahora, creo que es hora de agregar outputbox, veremos la salida html del código fuente de Markdown al escribir.

Para este fin, tenemos que agregar un HTMLLabel, en la función init_window así:

Usamos HTMLLabel en tkhtmlview, el ancho sigue siendo 1. Establecemos el ancho en 1 porque la ventana se compartirá entre el campo de entrada y el cuadro de salida en una proporción de 1: 1 (comprenderá lo que quiero decir cuando ejecute el script).

El parámetro de palabra clave html almacena el valor que se mostrará por primera vez.

Luego, empáquelo en la ventana y colóquelo a la DERECHA a la derecha del campo de entrada. fit_height () ajusta el texto al widget.

Ahora ejecute el código de la siguiente manera:

Construye un editor Markdown simple usando Python y Tkinter 

Ahora, si comienza a escribir en el campo de entrada, la salida no se actualizará a medida que escribe. Eso es porque no le hemos dicho a nuestro programa que haga esto.

Para hacer esto, primero debemos vincular un evento con el editor. Luego, cuando modifique el texto, la salida se actualizará de la siguiente manera:

self.inputeditor.bind ("<<Modified>>", self.onInputChange)

Ponga esta línea en la función init_window ().

Esta línea le dice a inputeditor que llame a la función onInputChange cuando el texto cambia. Pero debido a que todavía no tenemos esa función, necesitamos escribirla.

...
def onInputChange (self, event):
    self.inputeditor.edit_modified (0)
    md2html = Markdown ()
    self.outputbox.set_html (md2html.convert (self.inputeditor.get ("1.0", END)))

En la primera línea, usamos edit_modified (0) para restablecer el indicador modificado para que pueda reutilizarse. De lo contrario, ya no funcionará después de la primera llamada de evento.

A continuación, creamos un objeto Markdown llamado md2html. La última línea (la línea marcada en rojo arriba) , primero que nada ... ¡espera! La última línea puede confundir a algunos lectores. Lo dividí en tres líneas.

markdownText = self.inputeditor.get ("1.0", END)
html = md2html.convert (markdownText)
self.outputbox.set_html (html)

En la primera línea, obtenemos el texto de rebaja de arriba a abajo del campo de entrada. El primer parámetro, self.inputeditor.get, le dice que comience a escanear desde el carácter 0 de la primera línea (1.0 => [LINE_NUMBER]. [CHARACTER_NUMBER]), y el último parámetro le dice que deje de escanear cuando llegue al final.

Luego, usamos la función md2html.convert () para convertir el texto de marcado escaneado a html y almacenarlo en la variable html.

Finalmente, le decimos a outputbox que use la función .set_html () para mostrar la salida.

Ejecute el script Verá un editor de rebajas con funciones casi normales. Cuando ingresa un campo de entrada, la salida también se actualizará.

Pero ... nuestro trabajo no se ha completado. Los usuarios al menos necesitan poder abrir y guardar su texto.

Para esto, queremos agregar un menú de archivo en la barra de menú. Aquí, el usuario puede abrir y guardar el archivo, o salir de la aplicación.

En la función init_window, agregaremos la siguiente línea:

self.mainmenu = Menú (self)
self.filemenu = Menú (self.mainmenu)
self.filemenu.add_command (label = "打开", comando = self.openfile)
self.filemenu.add_command (label = "另存 为", comando = self.savefile)
self.filemenu.add_separator ()
self.filemenu.add_command (label = "退出", command = self.quit)
self.mainmenu.add_cascade (label = "文件", menu = self.filemenu)
self. master.config (menu = self.mainmenu)

Brevemente:

Aquí, definimos un nuevo menú con el marco como su menú principal.

A continuación, definimos otro menú y el menú anterior como su menú principal. Servirá como nuestro menú de archivos.

Luego use las funciones add_command () y add_separator () para agregar 3 submenús (abrir, guardar como y salir) y separadores. Al abrir el submenú se ejecutará la función de archivo abierto, y al guardar como submenú se ejecutará la función de guardar archivo. Finalmente, Exit ejecutará una función incorporada para salir, que cerrará el programa.

Luego use la función add_cascade () para decirle al primer objeto del menú que contenga la variable filemenu. Esto incluye todos los submenús en el archivo de etiqueta.

Finalmente, usamos self.master.config () para decirle a la ventana que use el menú principal como la barra de menú de la ventana.

Construye un editor Markdown simple usando Python y Tkinter

Se ve así, pero no lo ejecutes todavía. Se le indicará un error, las funciones de abrir archivo y guardar archivo no están definidas.

Como puede ver ahora, debemos definir dos funciones en la clase Window, en las que utilizaremos el diálogo de archivos de tkinter.

Primero definamos la función para abrir el archivo:

def openfile (self):
    openfilename = filedialog.askopenfilename (filetypes = (("Markdown File", "* .md, * .mdown, * .markdown"),
                                                                  ("Text File", "* .txt"),
                                                                  ( "Todos los archivos", "*. *")))
    Si el nombre de             archivo abierto :
        intente:
self.inputeditor.delete (1.0, END)
            self.inputeditor.insert (END, open (nombre de archivo abierto) .read ())
        excepto:
            print ("无法 打开 文件! ") 

Aquí, primero mostramos al usuario un cuadro de diálogo del explorador de archivos, que le permite usar filedialog.askopenfilename () para seleccionar el archivo que se abrirá. Con el argumento de la palabra clave filetypes, le decimos al cuadro de diálogo que solo abra estos tipos de archivos pasando una tupla con archivos compatibles (básicamente todos los tipos de archivos):

  • Archivos con extensiones .md, .mdown, .markdown,
  • Archivo de texto con extensión .txt
  • En la siguiente línea que usa la expansión comodín, le decimos al cuadro de diálogo que abra cualquier archivo con una extensión.

Luego verificamos si el usuario ha seleccionado un archivo. Si es así, intentamos abrir el archivo. Luego, elimine todo el texto en el campo de entrada desde el carácter 0 de la primera línea hasta el final del campo.

A continuación, abrimos y leemos el contenido del archivo seleccionado e insertamos el contenido en el campo de entrada.

Si nuestro programa no puede abrir un archivo, imprimirá un error. Pero espera, esta no es una buena manera de manejar los errores. Lo que podemos hacer aquí es mostrar un mensaje de error similar al del usuario:

Construye un editor Markdown simple usando Python y Tkinter

Para este fin, primero debemos importar el cuadro de mensaje cuadro de mensaje del paquete tkinter.

de tkinter import messagebox como mbox

Luego, en lugar de simplemente imprimir un mensaje de error como el anterior, reemplazaremos esa línea con la siguiente para mostrar el mensaje de error correcto al usuario.

mbox.showerror ("Se produjo un error al abrir el archivo seleccionado", "¡Vaya!, el archivo que seleccionó: {} no se pudo abrir!". format (openfilename))

Esto creará un mensaje de error, al igual que la captura de pantalla cuando el archivo que se muestra arriba no se puede abrir.

Función mbox.showerror, el primer parámetro es el título del cuadro de mensaje. El segundo es el mensaje que se mostrará.

Ahora, necesitamos escribir una función savefile para guardar la entrada de rebajas.

def savefile (self):
        filedata = self.inputeditor.get ("1.0", END)
        savefilename = filedialog.asksaveasfilename (filetypes = (("Markdown File", "* .md"),
                                                                  ("File Text", "* .txt ")), title =" 保存 Markdown 文件 ")
        if savefilename:
            intente:
                f = open (savefilename," w ")
                f.write (filedata)
            excepto:
                mbox.showerror (" 保存 文件 错误 "," 哎呀! , 文件: {} 保存 错误! ". Format (savefilename))

Aquí, primero escaneamos todo el contenido del campo de entrada y lo almacenamos en una variable. Luego, pasamos a dos tipos de archivos (.md y .txt).

Si el usuario elige un nombre de archivo, intentaremos guardar el contenido del campo de entrada almacenado en los datos variables del archivo. Si ocurre una excepción, mostraremos un mensaje de error al usuario que indica que el programa no puede guardar el archivo.

¡No olvide probar su aplicación para verificar si hay errores! Si su programa no tiene errores, debería funcionar perfectamente así:

Construye un editor Markdown simple usando Python y Tkinter

OK, esto es. ¿Lo has aprendido?

Supongo que te gusta

Origin www.linuxidc.com/Linux/2020-04/162830.htm
Recomendado
Clasificación