Mostrando entradas con la etiqueta Frame. Mostrar todas las entradas
Mostrando entradas con la etiqueta Frame. Mostrar todas las entradas

miércoles, 23 de marzo de 2022

El gestor de geometría Grid.


resultado del diseño


El gestor de geometría Grid con Tkinter y Guizero.

Este gestor de ventanas trata las mismas como si fueran una cuadrícula, formada por filas y columnas. El símil podría ser un tablero de ajedrez, donde se pueden situar las piezas, widgets en nuestro caso, dando la referencia de la columna y fila donde queremos colocarlo. Incluso, podemos indicarle a un elemento que ocupe más de una fila o columna. 

Con este gestor se pueden construir aplicaciones muy complejas, y hacer que los elementos se adapten a la misma, si las ventanas varían su tamaño.


Tkinter.


Grid con ventana no dimensionable. Ejemplo.


resultado con gestor grid


Empezamos con el mismo código que en el capitulo anterior.


from tkinter import *
from tkinter import ttk, font
import getpass

# Gestor de geometría (grid). Ventana no dimensionable

class Aplicacion():
    def __init__(self):
        self.raiz = Tk()
        self.raiz.title("Acceso")

Para hacer que una ventana no sea redimensionable se utiliza el método resizable(0,0) que es la forma abreviada de resizable(width = False, height = False)

                self.raiz.resizable(0,0)
        fuente = font.Font(weight='bold')


Crearemos un marco que contenga al resto de elementos. Este marco tiene un borde de 2 y la opción "relief". Vamos a utilizar esta opción para crear un efecto en 3d del marco.

 La opción relief puede tener los siguientes valores:

- FLAT (llano)

- RAISED (elevado)

- SUNKEN (hundido)

- GROOVE (hendidura)

- RIDGE (borde elevado) 

Luego utilizamos la opción "padding" para conseguir un espacio extra interior y que los widgets no queden pegados al marco. Otra forma sería usar padx y pady con cada uno de los widgets que usamos dentro del marco.

                 self.marco = ttk.Frame(self.raiz, borderwidth=2,
                               relief="raised", padding=(10,10))

Diseñaremos todos los elementos de la ventana con la diferencia de que los vamos a situar dentro del Frame (marco) que hemos creado.

                  self.etiq1 = ttk.Label(self.marco, text="Usuario:", 
                               font=fuente, padding=(5,5))
        self.etiq2 = ttk.Label(self.marco, text="Contraseña:",
                               font=fuente, padding=(5,5))
                               
        # Define variables para las opciones 'textvariable' de
        # cada caja de entrada 'ttk.Entry()'.
        
        self.usuario = StringVar()
        self.clave = StringVar()
        self.usuario.set(getpass.getuser())        
        self.ctext1 = ttk.Entry(self.marco, textvariable=self.usuario, 
                                width=30)
        self.ctext2 = ttk.Entry(self.marco, textvariable=self.clave, 
                                show="*", 
                                width=30)
        self.separ1 = ttk.Separator(self.marco, orient=HORIZONTAL)
        self.boton1 = ttk.Button(self.marco, text="Aceptar", 
                                 padding=(5,5), command=self.aceptar)
        self.boton2 = ttk.Button(self.marco, text="Cancelar", 
                                 padding=(5,5), command=quit)

Ahora viene la parte interesante, que es el colocar los elementos en las casillas o cuadrículas dentro del marco. En realidad habrá dos cuadrículas. Una de una fila por una columna que está en la ventana que ocupará el Frame (marco) y otra de cinco filas por tres columnas que ocuparán el resto de los widgets. Ten en cuenta que las filas y columnas se empiezan a contar en el cero. 

cuadricula de 5 x 3

Para seleccionar la casilla donde irá el widget, usaremos la opción "column" para indicar el número de la columna y la opción "row" para indicar la fila.
La opción "columnspan" indica al gestor cuantas columnas ocupará el widget en cuestión. 
Las cajas para las entradas self.ctext1 y self.ctext2 ocuparán dos columnas y la barra de separación self.separ1 ocupara tres columnas.

                 self.marco.grid(column=0, row=0)
        self.etiq1.grid(column=0, row=0)
        self.ctext1.grid(column=1, row=0, columnspan=2)
        self.etiq2.grid(column=0, row=1)
        self.ctext2.grid(column=1, row=1, columnspan=2)
        self.separ1.grid(column=0, row=3, columnspan=3, sticky="ew")
        self.boton1.grid(column=1, row=4)
        self.boton2.grid(column=2, row=4)

El diseño es algo como esto:

resultado del diseño


El resto del código es igual al del otro capítulo.


# Establece el foco en la caja de entrada de la
        # contraseña.

        self.ctext2.focus_set()
        self.raiz.mainloop()
    
    def aceptar(self):
        if self.clave.get() == 'herodoto':
            print("Acceso permitido")
            print("Usuario:   ", self.ctext1.get())
            print("Contraseña:", self.ctext2.get())
        else:
            print("Acceso denegado")
            self.clave.set("")
            self.ctext2.focus_set()

def main():
    mi_app = Aplicacion()
    return 0

if __name__ == '__main__':
    main()

En el siguiente enlace puedes encontrar el código del programa.


Grid con ventana dimensionable.

Tamaño standar.


Redimensionada.



Lo que vamos a ver ahora es como hacer lo mismo, pero cuando la ventana es dimensionable y tenemos que adaptar los widgets a ese aumento o disminución del tamaño de la ventana que los contiene.

El comienzo es el mismo que en el caso anterior. La parte que variará será a partir de que definamos la posición de los widgets en el marco.

from tkinter import *
from tkinter import ttk, font
import getpass

'''Gestor de geometría (grid). Ventana dimensionable'''


class Aplicacion():

    def __init__(self):
        self.raiz = Tk()
        self.raiz.title("Acceso")
         
        fuente = font.Font(weight='bold')

        self.marco = ttk.Frame(self.raiz, borderwidth=2,
                               relief='raised', padding=(10,10))

#         Define el resto de widgets pero en este caos el primer
#         parámetro indica que se situarán en el widget del marco
#         anterior 'self.marco'.

        self.etiq1 = ttk.Label(self.marco, text="Usuario:",
                               font=fuente, padding=(5,5))
        self.etiq2 = ttk.Label(
            self.marco, text="Contraseña:", font=fuente, padding=(5,5))

#         Define variables para las opciones 'textvariable' de
#         cada caja de entrada 'ttk.Entry()'.

        self.usuario = StringVar()
        self.clave = StringVar()
        self.usuario.set(getpass.getuser())
        self.ctext1 = ttk.Entry(self.marco, textvariable=self.usuario, width=30)
        self.ctext2 = ttk.Entry(self.marco, textvariable=self.clave, show="*", width=30)
        self.separ1 = ttk.Separator(self.marco, orient=HORIZONTAL)
        self.boton1 = ttk.Button(self.marco, text="Aceptar", padding=(5,5), command=self.aceptar)
        self.boton2 = ttk.Button(self.marco, text="Cancelar", padding=(5, 5), command=quit)

Para conseguir que cuando se amplíe o reduzca el tamaño de la ventana los widgets se adapten al mismo hay que introducir el parámetro "sticky", que viene del termino "pegajoso" en inglés. 

Cuando un widget se coloca en su cuadrícula lo hace en la parte central de la misma, la cual se adapta a su tamaño. Al usar este parámetro le estamos diciendo como tiene que comportarse cuando se modifiquen las dimensiones de la ventana. Se usan como valores los puntos cardinales en ingles: N (norte), S (sur), E (este) y W (oeste) solos o de forma combinada. El widget se quedará pegado a los lados de su celda en las direcciones que se indiquen. Aunque esto solo no basta, además de definir los stickies hay que activarlos, lo cual veremos en los siguientes pasos. 

Comencemos definiendo el sticky para cada uno de los elementos

                  self.marco.grid(column=0, row=0, sticky=(N,S,E,W))
        self.etiq1.grid(column=0, row=0, sticky=(N,S,E,W))
        self.ctext1.grid(column=1, row=0, columnspan=2, sticky=(E,W))
        self.etiq2.grid(column=0, row=1, sticky=(N,S,E,W))
        self.ctext2.grid(column=1, row=1, columnspan=2, sticky=(E,W))
        self.separ1.grid(column=1, row=3, columnspan=3, sticky="nsew")
        self.boton1.grid(column=1, row=4,sticky=(E))
        self.boton2.grid(column=2, row=4,sticky=(W))

Para a continuación pasar a activar la opción sticky, cuando la ventana aumente o disminuya de tamaño. La activación se hace por cada contenedor (Frame), y por cada fila y/o columna. Esto se lleva a cabo con el parámetro weight. Lo que vamos a hacer es asignar un peso (relativo) a cada fila o columna que va a servir para redistribuir ese nuevo espacio entre ambas.

Por ejemplo. Cuando se expanda la ventana una columna o fila que tenga un peso 2, crecerá dos veces más rápido que aquella que tenga un peso de 1. El valor predeterminado es el 0, lo que significa que la columna o fila que lo contenga no variará su tamaño. 

Lo habitual es asignar los pesos en las filas o columnas en los que haya widgets. En nuestro ejemplo el código podría quedar de la siguiente forma:

           # Repartimos el peso en cada contenedor.
        self.raiz.columnconfigure(0, weight=1)
        self.raiz.rowconfigure(0, weight=1)

        self.marco.columnconfigure(0, weight=1)
        self.marco.columnconfigure(1, weight=1)
        self.marco.columnconfigure(2, weight=1)
        self.marco.rowconfigure(0, weight=1)
        self.marco.rowconfigure(1, weight=1)
        self.marco.rowconfigure(4, weight=1)

El resto de la aplicación es igual que en el ejemplo anterior.

  # Establece el foco en la caja de entrada de la contraseña

        self.ctext2.focus_set()
        self.raiz.mainloop()

    def aceptar(self):
        if self.clave.get()=='herodoto':
            print('Acceso Permitido')
            print('Usuario:    ', self.ctext1.get())
            print('Contraseña: ', self.ctext2.get())
        else:
            print('Acceso denegado')
            self.clave.set("")
            self.ctext2.focus_set()

def main():
    mi_app = Aplicacion()
    return 0

if __name__=='__main__':
    main()

Puedes encontrar el código de este ejemplo en el siguiente enlace.


El gestor de geometría Grid con Guizero.


gestor de geometría grid con guizero



En este ejemplo vamos a explicar el método Grid en Guizero y utilizaremos un elemento de Tkinter como es el separador. Así veremos como usar elementos de tkinter en guizero y también como funciona el gestor Grid.

Empezamos importando todos los elementos de Guizero y también el elemento "Separator", solo que esta vez de la líbrería tkinter.tkk así como "HORIZONTAL" de Tkinter. Es widget no existe como tal en la librería de Guizero así que vamos a introducirlo de esta forma en el programa.


from guizero import *

#HORIZONTAL is Tkinter's variable. If you want to use it you have to import it or have to use like Tkinter.HORIZONTAL
#If you dont want to add Tkinter then you can do from Tkinter import HORIZONTAL
from tkinter import HORIZONTAL
# CUALQUIER VARIABLE DE TK QUE NO APAREZCA HAY QUE IMPORTARLA. 
from tkinter.ttk import Separator #Importamos el widget que necesitemos de ttk 
from getpass import getuser

def aceptar():
        
        if ctext2.value == 'herodoto':
            print('Acceso Permitido')
            print('Usuario:   ', ctext1.value)
            print('Contraseña: ', ctext2.value)
            ctext2.value="" #Borra el contenido del 2º cuadro de texto
            quit() #Sale del programa
        else:
            print('Acceso denegado')
            ctext2.value="" # Borra el contenido del 2º cuadro de texto si se falla.

usuario = getuser() # Captura el nombre del usuario que usa el sistema.

En Guizero tenemos también que especificar al contenedor cual es el gestor de ventanas que se va a utilizar. Si no ponemos nada por defecto es Pack.

Al igual que en los ejemplos anteriores vamos a usar una cuadrícula de tres columnas por cinco filas. El orden de colocación en el Grid también es (nº columna, nº fila). Ahora bien a diferencia de tkinter aquí definimos y colocamos el widget de una sola vez, en una instrucción. 

Para decir que un contenedor usa un gestor de geometría especifico se utiliza el parámetro "layout". En este caso como usamos el metodo Grid, el contenedor será Box(raiz, layout="grid").

A partir de ahí, al igual que en Tkinter, colocamos todos los widgets usando coordenadas. Aquí se usa el parámetro grid(nº columna, nº fila) empezando a contar desde el cero, al igual que anteriormente.

La forma de expandir los widgets para que ocupen varias casillas es un poco distinta a Tkinter. En vez de utilizar columspan o rowspan para ampliar las columnas que ocupa el widget, aquí se funciona de la siguiente forma.

Imagina que colocamos cualquier elemento en la columna 1 y en la fila 1. Se utilizaría para posicionarlo grid = [1,1]. Ahora bien si ese elemento tiene que expandirse a otras filas o columnas se utiliza la siguiente expresión:

grid = [1, 1, 1+[columnas a expandir], 1+(filas a expandir)]

Para que se entienda mejor. Si ese elemento que tenemos en la casilla [1, 1] queremos que ocupe dos columnas (la suya por colocación y una más hacia la derecha) usaremos grid = [1,1, 2, 1]. Si lo que queremos es que ocupe dos filas (la suya por colación y una fila más abajo) entonces usaremos grid = [1,1, 1, 2 ].

Dicho lo cual el resto del código es el siguiente.

raiz = App(width=390, height=120, title="Acceso")
raiz.tk.resizable(0, 0) # Es otra forma de decirle que la ventana es fija y no se puede cambiar el tamaño.

marco_sup = Box(raiz) # Creamos un marco normal, que se coloca arriba
Text(marco_sup, text="", size=5) # Pongo esto para separar lo siguiente del borde superior.

marco = Box(raiz, layout="grid") # el marco usará (3 columnas x 5 filas) grid.
# el tamaño de cada celda viene determinado por lo que contiene dentro. 

etiq1 = Text(marco, text="Usuario", grid=[0, 0], align='left', font='padmaa-Bold.1.1', size=14)
ctext1 = TextBox(marco, grid=[1, 0, 2, 1], width=30, align='left') # lo alineamos a la izquierda dentro del grid.
etiq1 = Text(marco, text="Contraseña", grid=[0, 1], align='left', font='padmaa-Bold.1.1', size=14) 
# size es el tamaño de la letra
ctext2 = TextBox(marco, grid=[1, 1, 2, 1], width=30, hide_text=True) 
# hide_text=True cambia las letras por *
# grid=[1,1,2,1] situa el grid en la columna 1 y fila 1 y luego lo expande 1 columnas y 0 fila (sumamos 1 a lo q queremos expandir)
# El grid no admite [1,1,0,0], xq por defecto  el grid [1,1] es como si fuera [1,1,1,1]
#x lo que expandir una columna seria [1,1,2,1] o expandir una fila [1,1,1,2]
#------------------------------------------------------------------------------------------

separ1 = Separator(marco.tk, orient=HORIZONTAL)
separ1.grid(column=1, row=3, columnspan=3, sticky="ew")
'''Para que un widget de tk o ttk funcione en guizero hay que diseñarlo y luego pack o grid o el gestor de
geometria que se use'''
#--------------------------------------------------------------------------------------------
boton1 = PushButton(marco, grid=[1, 4], text='Aceptar', padx=16, pady=6, command=aceptar)
boton2 = PushButton(marco, grid=[2, 4], text='Cancelar', padx=16, pady=6, command=quit)

ctext1.value=usuario
ctext2.focus() # Pone el foco en el cuadro 2 donde pondremos la contraseña.


raiz.display()

Nota: cualquier elemento de Guizero se basa en un widget de tkinter. Por eso al usar el separador que es un elemento de tkinker.tkk lo colocamos en el contenedor usando marco.tk y no solo el nombre marco.
Esto también ocurre si queremos utilizar propiedades de Tkinter en un elemento de Guizero, tendremos que usar la variable al que hayamos asignado el widget + sufijo.tk y el método de TKinter que queramos utilizar.


Puedes encontrar el código de este ejercicio en el siguiente enlace.

sábado, 19 de marzo de 2022

Lista de widgets en tkinter y guizero.


Imagen introductoria: widgets




Lista de Widgets en Tkinter y Guizero.


En este capítulo vamos a repasar algunos de los elementos más importantes que podemos encontrar en una aplicación Gráfica (GUI) y una descripción sencilla del código para generarlo tanto en Tkinter como en Guizero.

Ejemplos de código para los widgets de tkinter.
Ejemplos de código para los widgets de Guizero.

¿Que es un widget? 


Un widget describe cada una de las diferentes partes que pueden ser usadas para crear una interfaz de usuario o GUI
Aunque no te suenen sus nombre, reconocerás muchos de ellos en los diferentes programas o websites que utilizas.

El siguiente ejemplo muestra siete widgets en Guizero. Aunque sus nombres en Tkinter pueden variar un poco básicamente son los mismos, ya que recuerda que Guizero usa Tkinter para funcionar. 


diferentes widgets


Vamos a ir viéndolos uno a uno junto una pequeña descripción de su uso. Luego haremos un pequeño ejemplo con ambos programas para ver como programarlos. En otros capítulos veremos las diferentes propiedades y métodos que pueden tener cada uno y entraremos más en detalle.

Tipos de Widgets.

_______________________________________________________________________________
 
Nombre en Tkinter Nombre en Guizero
Frame Box

Es un widget que actúa como contenedor para otros widgets. Es invisible por defecto y puede ser usado para colocar más fácilmente otros widgets dentro de la ventana y alterar su diseño. En el ejemplo crearemos una caja (llámale Frame o Box) y colocamos dos botones dentro.

Tkinter
demostración de frame


from tkinter import *
# Creamos la aplicacion principal y su tamaño
raiz = Tk()
raiz.geometry("200x150")

# Creamos una caja alineada a la izquierda que ocupe toda la ventana y con borde
# para que podamos verlo.
frame=Frame(raiz)
frame.config(bg="lightblue")
frame.pack(side="left", fill="x", expand=1)

# Colocamos un boton dentro del Frame
button=Button(frame,text="botón")
button.pack()
# Colocamos otro boton dentro del mismo Frame
button1= Button(frame, text="Otro botón")
button1.pack()

raiz.mainloop()

Guizero

demostración de widget frame


# importamos la ventana principal, una caja y un botón
from guizero import App, Box, PushButton
# Creamos la aplicación principal
app = App(width=200, height=150)

# Creamos una caja alineada a la izquierda que ocupe toda la ventana y con borde
# para que podamos verlo.
box = Box(app, align="left", width="fill", border=2)
# Colocamos un botón
button = PushButton(box)
# Colocamos otro que se pone debajo
button1 = PushButton(box, text="another button")

app.display()
_______________________________________________________

Nombre en TkinterNombre en Guizero
ButtonPushButton

Es un botón que se puede pulsar y que sirve para una multitud de propósitos. Es uno de los que más frecuentemente se utiliza. Una vez que se pulsa lanza alguna acción en el programa. 

Tkinter

widget button en tkinter


from tkinter import *
 
def set():
    print("Hola Mundo")
 
root = Tk()
root.geometry("200x150")
 
frame = Frame(root)
frame.pack()
button = Button(frame, text = "Botón1", command = set,
                fg = "red", font = "Verdana 14 underline",
                bd = 2, bg = "light blue", relief = "groove")
button.pack(pady = 5)
 
root.mainloop()
Guizero

button widget en guizero



# importamos la ventana principal, una caja y un botón
from guizero import App, Box, PushButton

def set():
    print("Hola Mundo")
    
# Creamos la aplicación principal
app = App(width=200, height=150)

# Creamos una caja alineada a la izquierda que ocupe toda la ventana y con borde
# para que podamos verlo.
box = Box(app)
# Colocamos el botón con una serie de propiedades iniciales
button = PushButton(box, text="Botón1", command=set)
# Propiedades adicionales de los botones
button.bg="light blue"
button.text_color="red"
# incluso podemos usar directamente un método de tkinter en guizero
# <nombre>.tk.config()
button.tk.config(bd=2, relief = "groove",font = "Verdana 14 underline")
button.tk.pack(pady=5)
_______________________________________________________

Nombre en TkinterNombre en Guizero
EntryTextBox

Se usa para que el usuario pueda introducir datos desde la aplicación. Es una caja de texto en donde el usuario puede introducir datos.

Tkinter




from tkinter import *
 
root = Tk()
root.geometry("200x150")
 
frame = Frame(root)
frame.pack()
 
my_entry = Entry(frame, width = 20)
my_entry.insert(0,'Username')
my_entry.pack(padx = 5, pady = 5)
 
my_entry2 = Entry(frame, width = 15)
my_entry2.insert(0,'password')
my_entry2.pack(padx = 5, pady = 5)
 
root.mainloop()

Guizero



from guizero import App, TextBox, Box
raiz = App(width=200, height=150)

# no existen paddings para los box en guizero
# para lograr lo mismo hay que usar tkinter o como en
# este caso meter algo por medio.

# Caja de relleno que no se ve pero esta ahí
Box(raiz, align="top", width="fill", height=5)
# Caja Principal que contiene los inputs.
box = Box(raiz)

inputA = TextBox(box, width=20,text="Username")
inputB = TextBox(box, width=15, text="Password")
raiz.display()

_______________________________________________________

Nombre en TkinterNombre en Guizero
Check Button 
CheckBox

Las casillas de verificación permiten al usuario escoger entre un conjunto de acciones que ya están predefinidas. El usuario puede escoger más de una opción.


Tkinter

check button en tkinter


root = Tk()
root.geometry("200x150")
 
frame = Frame(root)
frame.pack()
 
Var1 = IntVar()
Var2 = IntVar()
 
ChkBttn = Checkbutton(frame, width = 15, text="Opción 1", variable = Var1)
ChkBttn.pack(padx = 5, pady = 5)
 
ChkBttn2 = Checkbutton(frame, width = 15, text="Opción2", variable = Var2)
ChkBttn2.pack(padx = 5, pady = 5)

root.mainloop()

Guizero

checkbox en guizero


from guizero import App, CheckBox, Box

# Creamos la aplicación principal
app = App(width=200, height=150)

# Creamos una contenedor
box = Box(app)
# Incorporamos las casillas de verificación.
checkbox_1 = CheckBox(box, text="Opción1")
checkbox_1 = CheckBox(box, text="Opción2")

app.display()

______________________________________________________

Nombre en TkinterNombre en Guizero
Radio Button 
ButtonGroup

Se muestra un conjunto de casillas de verificación redondas, en donde el usuario puede escoger una única opción.

Tkinter

Radio Button en tkinter


from tkinter import *
 
root = Tk()
root.geometry("200x150")
frame = Frame(root)
frame.pack()
 
Var1 = StringVar()
 
RBttn = Radiobutton(frame, text = "Option1", variable = Var1,
                    value = 1)
RBttn.pack(padx = 5, pady = 5)
 
RBttn2 = Radiobutton(frame, text = "Option2", variable = Var1,
                     value = 2)
RBttn2.pack(padx = 5, pady = 5)
 
root.mainloop()

Guizero.

En el ejemplo usamos un ButtonGroup que muestra la selección en una caja de texto.

ButtonGroup en guizero


from guizero import App, ButtonGroup, Text, Box

def update_text():
    seleccionada.value = opciones.value

app = App(width=200, height=150)
opciones = ButtonGroup(app, options=
                              ["Opción 1",
                              "Opción 2"],
                            selected="Opción 1", command=update_text)

caja = Box(app, border=2)
seleccionada = Text(caja, "Opción 1")
app.display()

______________________________________________________

Nombre en TkinterNombre en Guizero
LabelText, Picture

Muestra un texto dentro de la aplicación que el usuario no puede modificar. Es bastante útil para poner títulos, etiquetas o instrucciones. Es muy versátil y lo podemos usar incluso para incluir imágenes.

Tkinter.

Label en tkinter



from tkinter import *
 
root = Tk()
root.geometry("200x150")
 
frame = Frame(root)
frame.pack()
 
var = StringVar()
var.set("Hola Mundo")
 
label = Label(frame, textvariable = var )
label.pack()
 
root.mainloop()

Guizero.

text en guizero


from guizero import App, Text

app = App(width=200, height=150)

texto = Text(app, text="Hola Mundo!")

app.display()
* Usamos el widget Picture si en vez de mostrar un texto queremos que se incluya una imagen.

_____________________________________________________


Nombre en TkinterNombre en Guizero
MenuMenuBar

Este wigdet muestra un menú en la parte superior de la pantalla, y cada opción del menú conduce a un submenú.

Tkinter

Menu en Tkinter


from tkinter import *
 
def save():
    #Código a ser escrito
    pass
 
def load():
    #Código a ser escrito
    pass   
 
root = Tk()
root.geometry("200x150")
frame = Frame(root)
frame.pack()
 
mainmenu = Menu(frame)
mainmenu.add_command(label = "Save", command= save)  
mainmenu.add_command(label = "Load", command= load)
mainmenu.add_command(label = "Exit", command= root.destroy)
 
root.config(menu = mainmenu)
 
root.mainloop()
Guizero.

MenuBar en guizero


from guizero import App, MenuBar
def file_function():
    pass #codigo a rellenar

def edit_function():
    pass #codigo a rellenar
    
def exit_function():
    app.destroy()

app = App(width=200, height=150)
menubar = MenuBar(app,
                  toplevel=["Save", "Load", "Exit"],
                  options=[
                      [ ["Guardar", file_function], ["Guardar como..", file_function] ],
                      [ ["Cargar", edit_function], ["Cargar archivo", edit_function] ],
                      [ ["Salir", exit_function]],
                  ])
app.display()

_______________________________________________________

Nombre en TkinterNombre en Guizero
ComboBoxCombo

Este objeto lo que hace es mostrar un cuadro desplegable que permite seleccionar una sola opción dentro de una lista de opciones.

Tkinter.

Combobox de tkinter



from tkinter import *
from tkinter import ttk
 
root = Tk()
root.geometry("200x150")
 
frame = Frame(root)
frame.pack()
 
vlist = ["Option1", "Option2", "Option3",
          "Option4", "Option5"]
 
Combo = ttk.Combobox(frame, values = vlist)
Combo.set("Escoge una opción")
Combo.pack(padx = 5, pady = 5)
 
root.mainloop()

Guizero.

Combo en guizero


from guizero import App, Combo
app = App(width=200, height=150)
combo = Combo(app, options=["Opción 1", "Opción 2", "Opción 3"])
app.display()

_______________________________________________________

Nombre en TkinterNombre en Guizero
List Box
ListBox

Se utiliza para mostrar una lista de opciones al usuario en donde elegir. Se puede escoger una o varias de ellas.

Tkinter.

List box en tkinter


from tkinter import *
root = Tk()
root.geometry("200x220")
frame = Frame(root)
frame.pack()
 
label = Label(root,text = "Escoge elementos a comprar.")  
label.pack()  
   
listbox = Listbox(root)  
   
listbox.insert(1,"Pan")  
listbox.insert(2, "Leche")  
listbox.insert(3, "Carne")  
listbox.insert(4, "Queso")
listbox.insert(5, "Verduras")  
   
listbox.pack()  
root.mainloop()

Guizero.

ListBox en guizero

from guizero import App, ListBox, Text
app = App(width=200, height=150)
Text(app, text="lista de la compra")
listbox = ListBox(app, items=["Pan", "Leche", "Carne", "Queso"])
app.display()

______________________________________________________

Nombre en TkinterNombre en Guizero
Menu Button-


Es una combinación entre el widget de menú y el de botón. Muestra un menú desplegable con una lista de opciones cuando hacemos click en él. Este widget es único porque puede incorporar aspectos de botones de opción y de opciones de verificación.

Tkinter

Menu Button en tkinter


from tkinter import *
 
root = Tk()
root.geometry("200x150")
frame = Frame(root)
frame.pack()
 
MenuBttn = Menubutton(frame, text = "Favourite food", relief = RAISED)
 
Var1 = IntVar()
Var2 = IntVar()
Var3 = IntVar()
 
Menu1 = Menu(MenuBttn, tearoff = 0)
 
Menu1.add_checkbutton(label = "Pizza", variable = Var1)
Menu1.add_checkbutton(label = "Cheese Burger", variable = Var2)
Menu1.add_checkbutton(label = "Salad", variable = Var3)
 
MenuBttn["menu"] = Menu1
 
MenuBttn.pack()
root.mainloop()

______________________________________________________

Nombre en TkinterNombre en Guizero
CanvasDrawing

Aunque no son exactamente igual en ambas librerías, nos permite dibujar formas, imágenes o texto. Es como una pizarra en la que puedes pintar o dibujar cualquier cosa.

Tkinter.

Canvas en Tkinter


from tkinter import *
 
root = Tk()
 
frame=Frame(root,width=300,height=300)
frame.pack(expand = True, fill=BOTH)
 
canvas = Canvas(frame,bg='white', width = 300,height = 300)
 
coordinates = 20, 50, 210, 230
arc = canvas.create_arc(coordinates, start=0, extent=250, fill="blue")
arc = canvas.create_arc(coordinates, start=250, extent=50, fill="red")
arc = canvas.create_arc(coordinates, start=300, extent=60, fill="yellow")
 
canvas.pack(expand = True, fill = BOTH)
 
root.mainloop()

Guizero.

Drawing in guizero


from guizero import App, Drawing
app = App(width=200, height=150)
drawing = Drawing(app)
drawing.rectangle(10, 10, 60, 60, color="blue")
app.display()
_______________________________________________________


Nombre en TkinterNombre en Guizero
ScalaSlider


Este objeto muestra una barra y un selector que puede usarse para especificar un valor en un rango.

Tkinter.

Scala en tkinter


from tkinter import * 
 
root = Tk()
root.geometry("200x200")
frame = Frame(root)
frame.pack()
 
Scala = Scale(frame, from_=0, to=10)
Scala.pack(padx=5, pady=5)
 
Scala2 = Scale(frame, from_=0, to=10, orient=HORIZONTAL)
Scala2.pack(padx=5, pady=5)
 
root.mainloop()

Guizero.



from guizero import App, Slider
app = App(width=200, height=150)
slider = Slider(app, horizontal=False)
slider = Slider(app)
app.display()
______________________________________________________


Nombre en TkinterNombre en Guizero
ScrollBar-

Este widget nos va a permitir el desplazarnos por un ventana de Tkinter o mejor dicho habilitar el desplazamiento para ciertos widgets. Por lo general se usa cuando tienes un espacio limitado para una ventana en Tkinter pero quieres más espacio para el widget. Veámoslo con un ejemplo.

ScrollBar in tkinker


root.geometry("200x250") 
    
mylabel = Label(root, text ='Scrollbars', font = "30")  
mylabel.pack() 
 
myscroll = Scrollbar(root) 
myscroll.pack(side = RIGHT, fill = Y) 
 
mylist = Listbox(root, yscrollcommand = myscroll.set )  
for line in range(1, 100): 
    mylist.insert(END, "Number " + str(line)) 
mylist.pack(side = LEFT, fill = BOTH )    
 
myscroll.config(command = mylist.yview) 
    
root.mainloop() 

_______________________________________________________

Nombre en TkinterNombre en Guizero
ToplevelWindow

Este widget nos va a permitir nuevas ventanas.

Tkinter.



from tkinter import *
 
def NuevaVentana():
    window = Toplevel()
    window.geometry('150x150')
    newlabel = Label(window, text = "Settings Window")
    newlabel.pack()
 
 
root = Tk()
root.geometry('200x200')
 
myframe = Frame(root)
myframe.pack()
 
mybutton = Button(myframe, text = "Settings", command = NuevaVentana)
mybutton.pack(pady = 10)
 
root.mainloop()

Guizero.

window in guizero


from guizero import App, Window, PushButton

def open_window():
    window.show(wait=True)

app = App(title="My app", height=200, width=200)

window = Window(app, title = "2nd ventana", height=150, width=150)
# La ventana esta creada pero la ocultamos para que no se vea
# hasta que se pulse el botón que la vuelva visible.
window.hide()

open=PushButton(app, text="Segunda ventana", command=open_window)

app.display()

_______________________________________________________

Nombre en TkinterNombre en Guizero
Notebook


Este Widget nos permite seleccionar páginas de contenido haciendo clic en las pestañas.

Tkinter.



Cuando se hace clic en alguna de estas pestañas, el widget Notebook mostrará un panel secundario asociado a la pestaña seleccionada. Normalmente este panel secundario mostrado es un widget Frame de tkinter. 

Para crear este widget, usamos la clase ttk.Notebook de la siguiente forma:

notebook = ttk.Notebook(contenedor, opciones**)
Por lo general el contenedor suele ser la raíz del proyecto.

Este contenedor tiene algunas opciones útiles. Por ejemplo se puede especificar las opciones height and width para especificar el alto y ancho en pixeles asociados al widget.

Además también podemos agregar algo de espacio alrededor del widget usando la opción "padding".


Métodos del Notebook.


La clase ttk.Notebook tiene varios métodos que permiten gestionar las ventanas de una manera efectiva.

Veamos los más utilizados: 

add(child, Kwargs**)

El método add agrega un widget secundario a una ventana. Se le puede pasar una o más opciones.

child es el widget para agregar al Notebook o cuaderno.

La opción "text" especifica la etiqueta que aparecerá en la ventana. 

La opción "image" especifica la imagen que se mostrará en la pestaña.

Si usamos ambas tenemos que describir la posición de la imagen en relación al texto. Puede ser:
tk.TOP , tk.BOTTOM, tk.LEFT, tk.RIGHT o tk.CENTER.

La opción "underline" toma como valores 0 o un número positivo. Esto subraya el caracter que le indiquemos, pero solo uno. Si ponemos underline=0, solo subrayará el primer carácter, si ponemos 1 subrayará el segundo y así sucesivamente.

hide(tabId) 

Este método oculta temporalmente la pestaña identificada por el tabId del Notebook. Como siempre la primera pestaña es la 0, la siguiente la 1 y así sucesivamente.

Para volver a mostrar la ventana hay que volver a utilizar el método add() ya que en este caso no hay un método show()

forget(child)

Elimina permanentemente el widget indicado del Notebook.

El siguiente programa muestra como crear un Notebook con dos pestañas:

import tkinter as tk
from tkinter import ttk

# root window
root = tk.Tk()
root.geometry('400x300')
root.title('Ejemplo de Widget Notebook')

# create a notebook
notebook = ttk.Notebook(root)
notebook.pack(pady=10, expand=True)

# create frames
frame1 = ttk.Frame(notebook, width=400, height=280)
frame2 = ttk.Frame(notebook, width=400, height=280)

frame1.pack(fill='both', expand=True)
frame2.pack(fill='both', expand=True)

# add frames to notebook

notebook.add(frame1, text='Pestaña A', underline=1)
notebook.add(frame2, text='Pestaña B')


root.mainloop()

Guizero.

No existe un elemento especifico para crear un Notebook en guizero asi que tenemos que usar el elemento ttk.Notebook de tkinter.

from guizero import App, Box
from tkinter import ttk
from tkinter.ttk import Notebook

# set up app to use grid layout
app = App(title="Uso de ttk Notebook", layout="grid")

# set up box to use grid and place it in app at 0,0
box = Box(app, border=True, layout='grid', grid=[0,0])

# create a notebook
nb = Notebook(box.tk)

# create some frames for the tabs
pestana_a = ttk.Frame(nb)
pestana_b = ttk.Frame(nb)

# add the tabs
nb.add(pestana_a, text='Pestaña A')
nb.add(pestana_b, text='Pestaña B')

# important - add tk widget only after it is completed
box.add_tk_widget(nb, grid=[0,0])


app.display()
Puedes ver como usar esta forma de utilizar elementos de tk en Guizero en este enlace a la página del manual de Guizero.