72 - tkinter.ScrolledText : editor multilínea

Hemos visto anteriormente el control Entry que nos permite ingresar una cadena de caracteres por teclado. El Widget ScrolledText es similar al Widget Entry con la salvedad que nos permite ingresar múltiples líneas.

Cuenta con métodos sofisticados para extraer trozos del texto ingresado en la componente.

Para poder utilizar esta nueva componente debemos importar el módulo scrolledtext del paquete tkinter (podemos crear un alias para no tener que escribir scrolledtext):

from tkinter import scrolledtext as st

Problema:

Confeccionar un programa que contenga dos controles de tipo ScrolledText. En el primero ingresamos por teclado cualquier texto. Mediante 4 controles de tipo Entry indicar desde que fila y columna hasta que fila y columna extraer caracteres del primer ScrolledText y copiarlos al segundo ScrolledText cuando se presione un botón.

La interfaz visual debe ser similar a esta:

ScrolledText

Programa: ejercicio253.py

Ver video

import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext as st

class Aplicacion:
    def __init__(self):
        self.ventana1=tk.Tk()
        self.scrolledtext1=st.ScrolledText(self.ventana1, width=50, height=10)
        self.scrolledtext1.grid(column=0,row=0, padx=10, pady=10)
        self.framecopia()        
        self.scrolledtext2=st.ScrolledText(self.ventana1, width=50, height=10)
        self.scrolledtext2.grid(column=0,row=2, padx=10, pady=10)
        self.ventana1.mainloop()


    def framecopia(self):
        self.labelframe1=ttk.LabelFrame(self.ventana1, text="Region")
        self.labelframe1.grid(column=0, row=1, padx=5, pady=5, sticky="w")
        self.label1=ttk.Label(self.labelframe1, text="Desde fila:")
        self.label1.grid(column=0, row=0, padx=5, pady=5, sticky="e")
        self.dato1=tk.StringVar()
        self.entry1=ttk.Entry(self.labelframe1, textvariable=self.dato1)
        self.entry1.grid(column=1, row=0, padx=5, pady=5, sticky="e")
        self.label2=ttk.Label(self.labelframe1, text="Desde columna:")
        self.label2.grid(column=0, row=1, padx=5, pady=5, sticky="e")
        self.dato2=tk.StringVar()
        self.entry2=ttk.Entry(self.labelframe1, textvariable=self.dato2)
        self.entry2.grid(column=1, row=1, padx=5, pady=5, sticky="e")

        self.label3=ttk.Label(self.labelframe1, text="Hasta fila:")
        self.label3.grid(column=0, row=2, padx=5, pady=5, sticky="e")
        self.dato3=tk.StringVar()
        self.entry3=ttk.Entry(self.labelframe1, textvariable=self.dato3)
        self.entry3.grid(column=1, row=2, padx=5, pady=5, sticky="e")
        self.label4=ttk.Label(self.labelframe1, text="Hasta columna:")
        self.label4.grid(column=0, row=3, padx=5, pady=5, sticky="e")
        self.dato4=tk.StringVar()
        self.entry4=ttk.Entry(self.labelframe1, textvariable=self.dato4)
        self.entry4.grid(column=1, row=3, padx=5, pady=5, sticky="e")

        self.boton1=ttk.Button(self.labelframe1, text="Copiar", command=self.copiar)
        self.boton1.grid(column=1, row=4, padx=10, pady=10)


    def copiar(self):
        iniciofila=self.dato1.get()
        iniciocolumna=self.dato2.get()
        finfila=self.dato3.get()
        fincolumna=self.dato4.get()
        datos=self.scrolledtext1.get(iniciofila+"."+iniciocolumna, finfila+"."+fincolumna)
        self.scrolledtext2.delete("1.0", tk.END)        
        self.scrolledtext2.insert("1.0", datos)
        

aplicacion1=Aplicacion() 

Lo primero que hacemos es importar el módulo scrolledtext del paquete tkinter y definir un alias:

from tkinter import scrolledtext as st

Creamos y ubicamos cada uno de los ScrolledText en el método __init__:

    def __init__(self):
        self.ventana1=tk.Tk()
        self.scrolledtext1=st.ScrolledText(self.ventana1, width=50, height=10)
        self.scrolledtext1.grid(column=0,row=0, padx=10, pady=10)
        self.framecopia()        
        self.scrolledtext2=st.ScrolledText(self.ventana1, width=50, height=10)
        self.scrolledtext2.grid(column=0,row=2, padx=10, pady=10)
        self.ventana1.mainloop()

Separamos en el método framecopia la creación de la interfaz visual donde se cargan los 4 valores.

El método fundamental es el 'copiar':

    def copiar(self):
        iniciofila=self.dato1.get()
        iniciocolumna=self.dato2.get()
        finfila=self.dato3.get()
        fincolumna=self.dato4.get()
        datos=self.scrolledtext1.get(iniciofila+"."+iniciocolumna, finfila+"."+fincolumna)
        self.scrolledtext2.delete("1.0", tk.END)        
        self.scrolledtext2.insert("1.0", datos)

Para extraer cadenas de caracteres de un control ScrolledText debemos llamar la método get y pasar dos String. Por ejemplo si queremos extraer todos los caracteres de la primer fila hasta los 10 primeros caracteres de la tercer fila deberemos codificar:

        datos=self.scrolledtext1.get("1.0", "3.10") #fila 1 columna 0  hasta  fila 3 columna 10

En nuestro problema estos cuatro números los estamos cargando por teclado en los controles Entry.

Para borrar todo el contenido de un ScrolledText debemos llamar al método delete y pasar estos dos parámetros:

        self.scrolledtext2.delete("1.0", tk.END)        

Para insertar en cualquier parte de un ScrolledText empleamos el método insert:

        self.scrolledtext2.insert("1.0", datos)