Soluciones de ejercicios - Curso de 100 días de Python #16
Esta página contiene las soluciones para los ejercicios del día 16 del curso. Ejercicios dedicados a Tkinter de Python.
- Creamos 4 Radiobutton cada uno en una posición del grid, ocupando solo dos filas. No te olvides de poner los "value" serán importantes para los siguientes ejercicios.
#Importaciones from tkinter import * #Creación de la ventana principal root = Tk() #Título de la ventana root.title("www.programacionfacil.org") opcion = IntVar() #Radiobutton Radiobutton(root, text="Emma", variable=opcion, value=1).grid(row=0, column=0) Radiobutton(root, text="Jorge", variable=opcion, value=2).grid(row=1, column=0) Radiobutton(root, text="Pepe", variable=opcion, value=3).grid(row=0, column=1) Radiobutton(root, text="Amarillo", variable=opcion, value=4).grid(row=1, column=1) #Bucle de ejecución root.mainloop()
- Para hacer esto, solo tenías que aplicar los conocimientos mostrados en capítulos anteriores con las imágenes y el grid.
Fíjate en los Label de las imágenes. Algo que no te he comentado aún en el curso, es que por defecto, si no le pones que se muestre en la ventana root, se muestra en ella sin dar error. Puesto que no hay más sitios donde mostrar esos elementos u otros, está bien, pero esto te puede llevar a cometer fallos si haces modificaciones y no ves claro donde va cada elemento.
#Importaciones from tkinter import * import os from PIL import ImageTk,Image # Directorio de imágenes principal carpeta_principal = os.path.dirname(__file__) # Directorio de imágenes carpeta_imagenes = os.path.join(carpeta_principal, "imagenes") carpeta_logos = os.path.join(carpeta_imagenes, "logos") carpeta_usuarios = os.path.join(carpeta_imagenes, "usuarios") #Creación de la ventana principal root = Tk() #Título de la ventana root.title("American Rider Login") #Icono de la ventana root.iconbitmap(os.path.join(carpeta_logos, "logo.ico")) #Carga de imágenes #Usuario 1 usuario_1 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "emma.png")).resize((200,200))) etiqueta = Label(image=usuario_1) etiqueta.grid(row=0, column=0) #Usuario 2 usuario_2 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "noah.png")).resize((200,200))) etiqueta = Label(image=usuario_2) etiqueta.grid(row=2, column=0) #Usuario 3 usuario_3 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "jacob.png")).resize((200,200))) etiqueta = Label(image=usuario_3) etiqueta.grid(row=0, column=1) #Usuario 4 usuario_4 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "sophia.png")).resize((200,200))) etiqueta = Label(image=usuario_4) etiqueta.grid(row=2, column=1) opcion = IntVar() #Radiobutton Radiobutton(root, text="Emma", variable=opcion, value=1).grid(row=1, column=0) Radiobutton(root, text="Noah", variable=opcion, value=2).grid(row=3, column=0) Radiobutton(root, text="Jacob", variable=opcion, value=3).grid(row=1, column=1) Radiobutton(root, text="Sophia", variable=opcion, value=4).grid(row=3, column=1) #Bucle de ejecución root.mainloop()
- Solo había que poner el atributo background para los Radiobutton. Fíjate en las líneas 48, 54, 60 y 66.
#Importaciones from tkinter import * import os from PIL import ImageTk,Image # Directorio de imágenes principal carpeta_principal = os.path.dirname(__file__) # Directorio de imágenes carpeta_imagenes = os.path.join(carpeta_principal, "imagenes") carpeta_logos = os.path.join(carpeta_imagenes, "logos") carpeta_usuarios = os.path.join(carpeta_imagenes, "usuarios") #Creación de la ventana principal root = Tk() #Título de la ventana root.title("American Rider Login") #Icono de la ventana root.iconbitmap(os.path.join(carpeta_logos, "logo.ico")) #Carga de imágenes #Usuario 1 usuario_1 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "emma.png")).resize((200,200))) etiqueta = Label(image=usuario_1) etiqueta.grid(row=0, column=0) #Usuario 2 usuario_2 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "noah.png")).resize((200,200))) etiqueta = Label(image=usuario_2) etiqueta.grid(row=2, column=0) #Usuario 3 usuario_3 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "jacob.png")).resize((200,200))) etiqueta = Label(image=usuario_3) etiqueta.grid(row=0, column=1) #Usuario 4 usuario_4 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "sophia.png")).resize((200,200))) etiqueta = Label(image=usuario_4) etiqueta.grid(row=2, column=1) opcion = IntVar() #Radiobutton Radiobutton(root, text="Emma", variable=opcion, value=1, background="MediumPurple3").grid(row=1, column=0) Radiobutton(root, text="Noah", variable=opcion, value=2, background="DarkSlateGray4").grid(row=3, column=0) Radiobutton(root, text="Jacob", variable=opcion, value=3, background="olive drab").grid(row=1, column=1) Radiobutton(root, text="Sophia", variable=opcion, value=4, background="salmon").grid(row=3, column=1) #Bucle de ejecución root.mainloop()
- He añadido las líneas de la 20 a la 25. Es posible que hayas sufrido un poco haciendo esto entre el flujo de ejecución y como colocar los elementos y la mezcla de usar pack() y grid() que da error si se utiliza en el mismo contexto.
Con contexto, me refiero en root o en el marco.
Cada uno de estos lugares en la ventana, cuenta con su propio espacio para usar pack() y grid(). En un mismo espacio, no se puede usar pack() y grid(), por lo que primero, para aplicar un pack() al marco, debes especificar a los elementos que utilizan grid() en el root, que se muestren dentro del marco.
#Importaciones from tkinter import * import os from PIL import ImageTk,Image # Directorio de imágenes principal carpeta_principal = os.path.dirname(__file__) # Directorio de imágenes carpeta_imagenes = os.path.join(carpeta_principal, "imagenes") carpeta_logos = os.path.join(carpeta_imagenes, "logos") carpeta_usuarios = os.path.join(carpeta_imagenes, "usuarios") #Creación de la ventana principal root = Tk() #Título de la ventana root.title("American Rider Login") #Icono de la ventana root.iconbitmap(os.path.join(carpeta_logos, "logo.ico")) #Marco - Sección usuarios marco_usuarios = LabelFrame(root, text="Seleccione un usuario:", padx=10, pady=10) marco_usuarios.pack(padx=10, pady=10) #Carga de imágenes #Usuario 1 usuario_1 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "emma.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_1) etiqueta.grid(row=0, column=0) #Usuario 2 usuario_2 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "noah.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_2) etiqueta.grid(row=2, column=0) #Usuario 3 usuario_3 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "jacob.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_3) etiqueta.grid(row=0, column=1) #Usuario 4 usuario_4 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "sophia.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_4) etiqueta.grid(row=2, column=1) opcion = IntVar() #Radiobutton Radiobutton(marco_usuarios, text="Emma", variable=opcion, value=1, background="MediumPurple3").grid(row=1, column=0) Radiobutton(marco_usuarios, text="Noah", variable=opcion, value=2, background="DarkSlateGray4").grid(row=3, column=0) Radiobutton(marco_usuarios, text="Jacob", variable=opcion, value=3, background="olive drab").grid(row=1, column=1) Radiobutton(marco_usuarios, text="Sophia", variable=opcion, value=4, background="salmon").grid(row=3, column=1) #Bucle de ejecución root.mainloop()
Soluciones para los ejercicios opcionales
- Fíjate en la línea 20. Ahí le he puesto el color de fondo a la ventana. En la línea 27 le he puesto el fondo al marco y en la 28, le he quitado el borde.
#Importaciones from tkinter import * import os from PIL import ImageTk,Image # Directorio de imágenes principal carpeta_principal = os.path.dirname(__file__) # Directorio de imágenes carpeta_imagenes = os.path.join(carpeta_principal, "imagenes") carpeta_logos = os.path.join(carpeta_imagenes, "logos") carpeta_usuarios = os.path.join(carpeta_imagenes, "usuarios") #Creación de la ventana principal root = Tk() #Título de la ventana root.title("American Rider Login") #Icono de la ventana root.iconbitmap(os.path.join(carpeta_logos, "logo.ico")) root.configure(background="gray98") #Marco - Sección usuarios marco_usuarios = LabelFrame(root, text="Seleccione un usuario:", padx=10, pady=10, background="gray98", border=0) marco_usuarios.pack(padx=10, pady=10) #Carga de imágenes #Usuario 1 usuario_1 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "emma.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_1) etiqueta.grid(row=0, column=0) #Usuario 2 usuario_2 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "noah.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_2) etiqueta.grid(row=2, column=0) #Usuario 3 usuario_3 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "jacob.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_3) etiqueta.grid(row=0, column=1) #Usuario 4 usuario_4 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "sophia.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_4) etiqueta.grid(row=2, column=1) opcion = IntVar() #Radiobutton Radiobutton(marco_usuarios, text="Emma", variable=opcion, value=1, background="MediumPurple3").grid(row=1, column=0) Radiobutton(marco_usuarios, text="Noah", variable=opcion, value=2, background="DarkSlateGray4").grid(row=3, column=0) Radiobutton(marco_usuarios, text="Jacob", variable=opcion, value=3, background="olive drab").grid(row=1, column=1) Radiobutton(marco_usuarios, text="Sophia", variable=opcion, value=4, background="salmon").grid(row=3, column=1) #Bucle de ejecución root.mainloop()
- Lo primero que he hecho, está en las líneas 53 y 54. En ellas, he creado una variable de control StringVar(), la cual, admite valores string. Le pongo con set el valor por defecto de "Error". De esta forma, con un condicional if, podré evaluar fácilmente si el usuario ha pulsado un Radiobutton antes de pulsar el botón de envío.
En las líneas 60, 66, 72 y 78 tienes los nuevos values. Los cuales me servirán para formatearlos en la frase de bienvenida para cada usuario.
De las líneas 81 a la 99 está la función que permite evaluar si la variable "opcion" tiene "Error" al pulsar el botón. Esto querrá decir que no se ha seleccionado ninguna opción.
En caso contrario, se obtiene el valor de "opcion" correspondiente a la opción seleccionada.
#Importaciones from tkinter import * import os from PIL import ImageTk,Image # Directorio de imágenes principal carpeta_principal = os.path.dirname(__file__) # Directorio de imágenes carpeta_imagenes = os.path.join(carpeta_principal, "imagenes") carpeta_logos = os.path.join(carpeta_imagenes, "logos") carpeta_usuarios = os.path.join(carpeta_imagenes, "usuarios") #Creación de la ventana principal root = Tk() #Título de la ventana root.title("American Rider Login") #Icono de la ventana root.iconbitmap(os.path.join(carpeta_logos, "logo.ico")) root.configure(background="gray98") #Marco - Sección usuarios marco_usuarios = LabelFrame(root, text="Seleccione un usuario:", padx=10, pady=10, background="gray98", border=0) marco_usuarios.pack(padx=10, pady=10) #Carga de imágenes #Usuario 1 usuario_1 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "emma.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_1) etiqueta.grid(row=0, column=0) #Usuario 2 usuario_2 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "noah.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_2) etiqueta.grid(row=2, column=0) #Usuario 3 usuario_3 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "jacob.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_3) etiqueta.grid(row=0, column=1) #Usuario 4 usuario_4 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "sophia.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_4) etiqueta.grid(row=2, column=1) opcion = StringVar() opcion.set("Error") #Radiobutton Radiobutton(marco_usuarios, text="Emma", variable=opcion, value="Emma", background="MediumPurple3").grid(row=1, column=0) Radiobutton(marco_usuarios, text="Noah", variable=opcion, value="Noah", background="DarkSlateGray4").grid(row=3, column=0) Radiobutton(marco_usuarios, text="Jacob", variable=opcion, value="Jacob", background="olive drab").grid(row=1, column=1) Radiobutton(marco_usuarios, text="Sophia", variable=opcion, value="Sophia", background="salmon").grid(row=3, column=1) # Función para el botón de envío def actualiza_radio(): if opcion.get() == "Error": Label(root, text=f"¡No has seleccionado ninguna cuenta! Por favor, inténtelo de nuevo", background="gray98", foreground="red2").pack() else: Label(root, text=f"Hola {opcion.get()}. Accediendo a tu cuenta personal...", background="gray98" ).pack() print(opcion.get()) # Botón de envío boton_envia = Button(root, text="Entrar", command=actualiza_radio, ).pack(pady=10) #Bucle de ejecución root.mainloop()
- Para esto, he creado otra carpeta llamada "graficos", en la cual iré guardando cosas como los botones de imagen. En la línea 12 tienes la línea de carga de esta carpeta.
En las líneas 53 y 54 tienes la carga de la imagen. No la muestro todavía.
En botón, añado la opción "image" que hemos usado hasta ahora en las etiquetas Label(). Esto hará que la imagen se visualice como fondo en el botón.
Finalmente, hay que poner un borde 0 para quitar los bordes por defecto del botón. Mostrando una imagen redondeada sin morir en el intento haciéndolo mediante código.
#Importaciones from tkinter import * import os from PIL import ImageTk,Image # Directorio de imágenes principal carpeta_principal = os.path.dirname(__file__) # Directorio de imágenes carpeta_imagenes = os.path.join(carpeta_principal, "imagenes") carpeta_logos = os.path.join(carpeta_imagenes, "logos") carpeta_usuarios = os.path.join(carpeta_imagenes, "usuarios") carpeta_graficos = os.path.join(carpeta_imagenes, "graficos") #Creación de la ventana principal root = Tk() #Título de la ventana root.title("American Rider Login") #Icono de la ventana root.iconbitmap(os.path.join(carpeta_logos, "logo.ico")) root.configure(background="gray98") #Marco - Sección usuarios marco_usuarios = LabelFrame(root, text="Seleccione un usuario:", padx=10, pady=10, background="gray98", border=0) marco_usuarios.pack(padx=10, pady=10) #Carga de imágenes #Usuario 1 usuario_1 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "emma.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_1, background="gray98") etiqueta.grid(row=0, column=0) #Usuario 2 usuario_2 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "noah.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_2, background="gray98") etiqueta.grid(row=2, column=0) #Usuario 3 usuario_3 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "jacob.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_3, background="gray98") etiqueta.grid(row=0, column=1) #Usuario 4 usuario_4 = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_usuarios, "sophia.png")).resize((200,200))) etiqueta = Label(marco_usuarios, image=usuario_4, background="gray98") etiqueta.grid(row=2, column=1) #Boton entrar boton_entrar = ImageTk.PhotoImage(Image.open(os.path.join(carpeta_graficos, "boton_enviar.png"))) opcion = StringVar() opcion.set("Error") #Radiobutton Radiobutton(marco_usuarios, text="Emma", variable=opcion, value="Emma", background="MediumPurple3").grid(row=1, column=0) Radiobutton(marco_usuarios, text="Noah", variable=opcion, value="Noah", background="DarkSlateGray4").grid(row=3, column=0) Radiobutton(marco_usuarios, text="Jacob", variable=opcion, value="Jacob", background="olive drab").grid(row=1, column=1) Radiobutton(marco_usuarios, text="Sophia", variable=opcion, value="Sophia", background="salmon").grid(row=3, column=1) # Función para el botón de envío def actualiza_radio(): if opcion.get() == "Error": Label(root, text=f"¡No has seleccionado ninguna cuenta! Por favor, inténtelo de nuevo", background="gray98", foreground="red2").pack() else: Label(root, text=f"Hola {opcion.get()}. Accediendo a tu cuenta personal...", background="gray98" ).pack() # Botón de envío boton_envia = Button(root, text="Entrar", command=actualiza_radio, image=boton_entrar, border=0, background="gray98" ).pack(pady=10) #Bucle de ejecución root.mainloop()