Bienvenido a Tecnohackers

Tecnohackers » Programacion » Area de Programacion » Scripting. VBS, Batch, Bash, JavaSript.
 » 

Crear menus profecionales en Tkinter. by Sokoleonardo



Autor Tema: Crear menus profecionales en Tkinter. by Sokoleonardo  (Leído 1168 veces)

Desconectado Sokoleonardo

  • Habitual
  • **
  • Mensajes: 116
  • ¡¡¡ORGULLO DE SER ARGENTINOO!!!
Crear menus profecionales en Tkinter. by Sokoleonardo
« en: Febrero 22, 2012, 07:13:35 pm »
Hice este tutorial donde crearemos menus basicos y artisticos.

Se asume que para leer este tuturial se debe tener una sierta habilidad con Tkinter.


Crear menus profecionales en Tkinter...

Bien empecemos...

Tenemos que crear una plantilla para empezar el ejemplo:
Primero veremos el "menu normal"

Código: You are not allowed to view links. Register or Login
from Tkinter import * #importamos

ventana = Tk() #ventana base
ventana.geometry("300x200") #tamaño de ventana
ventana.title("Menus") #titulo


 #codigo del programa


ventana.mainloop() #bucle del programa
Ahora guardamos el codigo en la extencion de Python

Luego seguimos...


Ahora crearemos el "menu normal".

primero tenemos que crear el objeto Menu.

Código: You are not allowed to view links. Register or Login
from Tkinter import *

ventana = Tk()
ventana.geometry("300x200")
ventana.title("Menus")

def Funcion():
    print "Funcion Ejecutada por usuario usando el menu"

menu_general = Menu(ventana) #incrustamos un menu en la ventana, aunque todabia no es visible
ventana["menu"] = menu_general #hacemos que la ventana tenga de menu a "menu_general", todabia no es visible

ventana.mainloop() #bucle del programa
Si ejecutan el codigo anterior veran que todabia no es visible.

Sigamos...

Código: You are not allowed to view links. Register or Login
from Tkinter import *

ventana = Tk()
ventana.geometry("300x200")
ventana.title("Menus")

def Funcion():
    print "Funcion Ejecutada por usuario usando el menu"

menu_general = Menu(ventana) #incrustamos un menu en la ventana, aunque todabia no es visible
ventana["menu"] = menu_general #hacemos que la ventana tenga de menu a "menu_general"

menu_archivo = Menu(menu_general) #menu archivo
menu_archivo.add_command(label = "Abrir archivo", command = Funcion)
menu_archivo.add_command(label = "Abrir carpeta", command = Funcion)
menu_archivo.add_command(label = "Buscar archivos", command = Funcion)
menu_archivo.add_separator()
menu_archivo.add_command(label = "Salir", command = ventana.destroy)
menu_general.add_cascade(label = "Archivo", menu = menu_archivo)

menu_ayuda = Menu(menu_general) #menu ayuda
menu_ayuda.add_command(label = "Acerca de...", command = Funcion)
menu_ayuda.add_command(label = "Visit my site", command = Funcion)
menu_general.add_cascade(label = "Ayuda", menu = menu_ayuda)

ventana.mainloop() #bucle del programa
Como vemos ahora el menu si es visible si lo ejecutamos.



Seguimos?...

Ahora vamos a explicarlo todo.

Código: You are not allowed to view links. Register or Login
menu_general = Menu(ventana) #incrustamos un menu en la ventana, aunque todabia no es visible
Eso hace que pongamos el menu sobre la ventana, y este menu tendra muchos menus colgados, por ejemplo si habrimos el programa "block de notas": no damos cuenta que tiene menus en la cima del programa, el menu contiene "Archivo", "Edicion", "Formato", "Ver" y "Ayuda". y sai hacemos click sobre "Archivo" se desplega un nuevo menu que tendra comandos con etiqueta como: "Nuevo", "Abrir...", "Guardar", "Guardar como..." y tendra un separador que separa las etiquetas que realizen utilidades que no tengan mucho que ver con las anteriores utilidades, luego tiene las etiquetas: "Configurar pagina...", "Imprimir" luego otro separador y luego tiene el comando etiquetado como "Salir".

Entonces sigo explicando lo que hace el codigo que he publicado con anterioridad:
El objeto Tk (Lo instanciamos con el nombre de "ventana"): tiene un atributo llamado "menu" al cual lo cambiamos como si estubieramos asignando un valor a un diccionario:

Código: You are not allowed to view links. Register or Login
ventana["menu"] = menu_general #hacemos que la ventana tenga de menu a "menu_general"
Todabia no es visible si lo ejecutas hasta esa linea del codigo.


Luego habiamos creado un menu al cual le añadimos etiquetas visuales con comandos que seria un menu que ejecuta funciones cada vez que hacemos un click sobre el.

Código: You are not allowed to view links. Register or Login
menu_archivo = Menu(menu_general) #menu archivo
Ahi vemos que lo incrustamos en el "menu_genral" para que luego pueda ser visible, tambien podemos incrustarlo en ventana, aunque es aconsejable que lo incrustes en "menu_general" como en el ejemplo que hice ya que te sirve de practica para los menus mas artisticos que veremos mas adelante.

Luego le agregamos comandos, que mas adelante los haremos visibles:

Código: You are not allowed to view links. Register or Login
menu_archivo.add_command(label = "Abrir archivo", command = Funcion)
...Al cual le pasamos una funcion con nombre "Funcion" que ejecuta el codigo que quieras.

Hay que aclarar que el menu todabia no es visible.

Ahora lo hacemos visible recien en esta parte del codigo:

Código: You are not allowed to view links. Register or Login
menu_general.add_cascade(label = "Archivo", menu = menu_archivo)
Entonces ahora recien se comporta de forma visible en "ventana". Ya que hemos agregado una cascada que despliega un menu llamado "menu_archivo".

Hay que aclarar que el codigo:

Código: You are not allowed to view links. Register or Login
menu_archivo.add_separator()
... agrega un separador el cual usaremos para separar un comando/s que no tengan mucho que ver con los comandos anteriores, por ejemplo el comando que abre un archivo no tiene mucho que ver con el comando salir o cerrar ya que realizan tareas diferentes aunque ambos comandos los ponemos en un menu llamado "Archivo" en este caso.

Luego creamos el menu "Ayuda" instanciado con el nombre "menu_ayuda":

Código: You are not allowed to view links. Register or Login
menu_ayuda = Menu(menu_general) #menu ayuda
menu_ayuda.add_command(label = "Acerca de...", command = Funcion)
menu_ayuda.add_command(label = "Visit my site", command = Funcion)
menu_general.add_cascade(label = "Ayuda", menu = menu_ayuda)
... Este menu estara luego del menu "Archivo"

Luego le damos un bucle al programa para que la ventana no destruya, sin este bucle el programa continuaria las lineas siguientes y en algun momento se terminaria el programa, este bucle permite al usuario de la aplicacion hacer lo suyo de manera que el programa se quede quieto y el usuario lo maneje todo atravez de teclado y mouse en una ventana con interfaz grafica.

Código: You are not allowed to view links. Register or Login
ventana.mainloop() #bucle del programa
Hay que aclarar algo mas...
El objeto Menu tambien acepta un parametro llamado background, y lo podes usar para poner el color de fondo a nuestro menu, aunque el "menu_general" no hace este cambio de color si hacemos:

Código: You are not allowed to view links. Register or Login
menu_general = Menu(ventana, background = "green") #incrustamos un menu en la ventana, aunque todabia no es visible
... como vemos acepta el parametro pero no es visible en la ventana eso veremos como cambiar de color en los siguientes menus artisticos que veremos adelante y despues de esta clase demu que ocupamos.

Ahora veremos que los metodos menu_archivo.add_command(label = "Abrir archivo", command = Funcion) tambien aceptan estos parametros como background, foreground, activebackground, activeforeground. Tambien acepta parametros como image, compound, siendo image para poner imagenes y compound para poner la imagen sobre el comando, y el parametro compound acepta direcciones como LEFT, RIGHT... indicando donde queremos la imagen, si especificamos una imagen a tener con el parametro image del metodo add_command entonces necesitaremos usar el comando compound ya que este ayuda a situar la imagen siendo el texto visible que hayamos puesto con el metodo add_command y el parametro text = "texto de comando".




Bueno ya hemos visto todo sobre los menus basicos, ahora veremos los menus artisticos o retocados con colores e imagenes (yo los llamo "LabelFrame+Menubutton+Menu/s")..

Ya les enseñe a usar el parametro background o otros metodos que modifiquen al menu de forma visual sobre el objeto Menu, pero ahora hablaremos sobre ellos en este siguiente capitulo pero de menus verdaderamente profecionales.


Código: You are not allowed to view links. Register or Login
from Tkinter import *

ventana = Tk()
ventana.geometry("300x200")
ventana.title("Menus")
ventana["background"] = "black"

def Funcion():
    print "Funcion Ejecutada por usuario usando el menu"

menu_general = LabelFrame(ventana, background = "#1C27BA") # el LabelFrame es necesario como base para apoyar los menus sobre el
menu_general.pack(side = TOP, fill = X)

boton_menu_archivo = Menubutton(menu_general, text = "Archivo", background = "#1C55BA", foreground = "#23A3FF",
                                activebackground = "#2355FF", activeforeground = "#70DBFF")  #creamos el boton del menu del cual despus desplegamos los menus
boton_menu_archivo.pack(side = LEFT) #ahora si es verdaderamente visible





ventana.mainloop()
Como vemos a "menu_general" ahora es LabelFrame ya que LabelFrame permite apoyar objetos de Tkinter sin problemas visuales sobre su base.


Veamos un ejemplo de menu artistico y luego explico todo:

Necesitaran estas imagenes:

You are not allowed to view links. Register or Login

You are not allowed to view links. Register or Login

You are not allowed to view links. Register or Login

You are not allowed to view links. Register or Login


Código: You are not allowed to view links. Register or Login
# -*- coding: utf-8 -*-
from Tkinter import *

ventana = Tk()
ventana.geometry("300x200")
ventana.title("Menus")
ventana["background"] = "black"


#Para editor de imagenes no usen editores como paint porque la imagen de salida es defectuosa y Tkinter no las admite.
#Es 100% recomendable usar IconLove como editor.
#Imagenes, nombres asociados:
imagen_carpeta = PhotoImage("carpeta", file = "carpeta32x32.gif")  #tamaño 32x32
imagen_archivo = PhotoImage("archivo", file = "archivo32x32.gif")  #tamaño 32x32
imagen_busqueda = PhotoImage("busqueda", file = "busqueda32x32.gif")  #tamaño 32x32
imagen_salida = PhotoImage("salida", file = "salida32x32.gif")  #tamaño 32x32

def Funcion():
    print "Funcion Ejecutada por usuario usando el menu"

menu_general = LabelFrame(ventana, background = "#1C27BA") # el LabelFrame es necesario como base para apoyar los menus sobre el
menu_general.pack(side = TOP, fill = X)

boton_menu_archivo = Menubutton(menu_general, text = "Archivo", background = "#1C55BA", foreground = "#23A3FF",
                                activebackground = "#2355FF", activeforeground = "#70DBFF")  #creamos el boton del menu del cual despus desplegamos los menus
boton_menu_archivo.pack(side = LEFT) #ahora si es verdaderamente visible

menu_archivo = Menu(boton_menu_archivo, background = "#1C55BA", foreground = "#23A3FF",
                    activebackground = "#474AFF", activeforeground = "#70DBFF")
menu_archivo.add_command(label = "Abrir archivo", image = "archivo", compound = LEFT, command = Funcion)
menu_archivo.add_command(label = "Abrir carpeta", image = "carpeta", compound = LEFT, command = Funcion)
menu_archivo.add_command(label = "Buscar archivo", image = "busqueda", compound = LEFT, command = Funcion)
menu_archivo.add_separator()
menu_archivo.add_command(label = "Salir", image = "salida", compound = LEFT, command = ventana.destroy)

boton_menu_archivo["menu"] = menu_archivo

ventana.mainloop()



Ahora vemos que todo es mas diferente a los menus basicos, primero expliquemos estas lineas:

Código: You are not allowed to view links. Register or Login
imagen_carpeta = PhotoImage("carpeta", file = "carpeta32x32.gif")  #tamaño 32x32
imagen_archivo = PhotoImage("archivo", file = "archivo32x32.gif")  #tamaño 32x32
imagen_busqueda = PhotoImage("busqueda", file = "busqueda32x32.gif")  #tamaño 32x32
imagen_salida = PhotoImage("salida", file = "salida32x32.gif")  #tamaño 32x32
Estas son imagenes las cuales podemos usar luego en objetos de Tkinter que admitan imagenes, el primer parametro es el nombre que llevara la imagen, segundo le especificamos a file que toma una cadena indicando el archivo, tenes que tener cuidado con los tamaños en las imagenes ya que los objetos de Tkinter seran agrandados segun el tamaño de la imagen, en este caso use cuidadosamente 32x32

Código: You are not allowed to view links. Register or Login
menu_general = LabelFrame(ventana, background = "#1C27BA") # el LabelFrame es necesario como base para apoyar los menus sobre el
menu_general.pack(side = TOP, fill = X)
Con esto estamos poniendo una base para los menus que luego estaran apoyados como "Archivo", "Editar", "Ayuda", etc.
Si pondriamos un Frame por ejemplo en vez de LabelFrame tendriamos problemas con la visualizacion del objeto que hayamos puesto sobre "menu_general", por ejemplo en algunas ocaciones seria invisible, por esto es que LabelFrame es ideal para base sobre la que incrustar todos los objetos que queramos sin problemas.

Ahora veamos esto:
El Menubutton es una especie de boton para los menus...

Código: You are not allowed to view links. Register or Login
boton_menu_archivo = Menubutton(menu_general, text = "Archivo", background = "#1C55BA", foreground = "#23A3FF",
                                activebackground = "#2355FF", activeforeground = "#70DBFF")
boton_menu_archivo.pack(side = LEFT)
... con esto ponemos un boton de menu sobre "menu_general", y sobre este Menubutton el usuario hace con tan solo un click desprenderse un menu que le hayamos puesto sobre ese Menubutton.

Ahora vamos a ver la parte importante:

Código: You are not allowed to view links. Register or Login
menu_archivo = Menu(boton_menu_archivo, background = "#1C55BA", foreground = "#23A3FF",
                    activebackground = "#474AFF", activeforeground = "#70DBFF")
menu_archivo.add_command(label = "Abrir archivo", image = "archivo", compound = LEFT, command = Funcion)
Lo primero que hace esto es instanciar una clase Menu con el nombre de "menu_archivo", a este menu lo usamos para meterlo en el Menubutton, a continuacion se explica como:

Código: You are not allowed to view links. Register or Login
boton_menu_archivo["menu"] = menu_archivo
La clase Menubutton tiene un atributo llamado "menu" el cual le asignamos el "menu_archivo"

Bueno creo que como veran las imagenes que le pusimos a nuestro menu agranda las etiquetas de los comandos, por ejemplo se agrando el comando "Abrir archivo", lo ven aqui:
Código: You are not allowed to view links. Register or Login
menu_archivo.add_command(label = "Abrir archivo", image = "archivo", compound = LEFT, command = Funcion)
... se agrando porque le pasamos una imagen de 32x32 la cual agrando los bordes de la etiqueta "Abrir archivo" sobre el menu... y todos los otros comandos que tambien le pusimos imagenes se agrandaron.

Ya estamos terminando con esto de los menus, ahora veremos un par de cositas:

Usamos el metodo "add_command" y "add_separator" de la clase Menu, pero tambien existen otros metodos por ejemplo add_checkbutton y add_cascade; son tambien muy buenas herramientas.
Veremos el ejemplo con un menu no tan retocado o artistico como el anterior si no como el que hablamos al principio del tutorial:
Código: You are not allowed to view links. Register or Login
from Tkinter import *

ventana = Tk()
ventana.geometry("300x200")
ventana.title("Menus")
ventana["background"] = "black"

def ChequeoBool():
    #revisamos el estado de la variable de checkbutton
    print {1: "seleccionado", 0: "No seleccionado"}[bool_tabulacion.get()]

menu_general = Menu(ventana)
ventana["menu"] = menu_general

menu_opciones = Menu(menu_general)
bool_tabulacion = IntVar()
menu_opciones.add_checkbutton(label = "Admitir tabulaciones", variable = bool_tabulacion, command = ChequeoBool)

menu_general.add_cascade(label = "Opciones", menu = menu_opciones)

ventana.mainloop()
...el parametro selectcolor del metodo add_checkbutton indica el color que tendra el selector del checkbutton

Ahora pasemos a una definicion mas aceptable sobre el metodo add_cascade.
Como vemos en los ejemplos anteriores usamos el metodo add_cascade de la clase Menu para poder añadir a la base de los menus un label sobre el que hacemos click y se desplega un menu, pero eso no es todo lo que podemos hacer con add_cascade, tambien veremos que se puede usar submenus que se desplegan de los menus que fueron desplegados con anterioridad.

veamos...

Código: You are not allowed to view links. Register or Login
from Tkinter import *

ventana = Tk()
ventana.geometry("300x200")
ventana.title("Menus")
ventana["background"] = "black"

menu_general = Menu(ventana)
ventana["menu"] = menu_general

menu_archivo = Menu(menu_general)
menu_general.add_cascade(label = "Archivo", menu = menu_archivo)

menu_archivo.add_command(label = "Abrir")
menu_archivo.add_command(label = "Cerrar")
menu_archivo.add_separator()
#a continuacion un submenu:
menu_archivo_recientes = Menu(menu_archivo) # se apolla en menu_archivo aunque todabia no es visible
menu_archivo_recientes.add_command(label = "C:/MyArchivo.py")
menu_archivo_recientes.add_command(label = "C:/StratoArchivo.py")
menu_archivo_recientes.add_command(label = "C:/Stratovarius.mp3")
menu_archivo_recientes.add_command(label = "C:/Practica.c")
menu_archivo.add_cascade(label = "Recientes", menu = menu_archivo_recientes) #ahora recien es visible
menu_archivo.add_separator()

menu_archivo.add_command(label = "Salir", command = ventana.destroy)

ventana.mainloop()
Ahora veremos por ultimo metodos de gran ayuda para los objetos Menu:

post(x, y) # este metodo es de gran ayuda por ejemplo cuando queremos que cuando el usuario haga un click derecho sobre algun objeto se desprenda el menu "Copiar", "Pegar" o "Borrar seleccionado" son ejemplos; sobre la "pantalla" cuando digo pantalla me refiero al x, y (parametros) de post que indican x (de derecha hacia izquierda de pantalla) y el parametro y (desde arriba hacia abajo de pantalla)

Veamos el ejemplo y esta vez sin que el menu se encaje en alguna base de la ventana:

Código: You are not allowed to view links. Register or Login
from Tkinter import *


ventana = Tk()
ventana.geometry("300x200")
ventana.title("Menu portapapeles")
ventana["background"] = "gray80"


entrada_datos = Entry(ventana, fg = "blue")
entrada_datos.pack()

def copiar():
    ventana.clipboard_append(entrada_datos.get())

def pegar():
    entrada_datos.insert("end", ventana.clipboard_get())

def borrar():
    entrada_datos.delete(0, "end")

def seleccionar():
    entrada_datos.select_range(0, "end")

menu_portapapeles = Menu(ventana, title = "Mi portapapeles")
menu_portapapeles.add_command(label = "Copiar", command = copiar)
menu_portapapeles.add_command(label = "Pegar", command = pegar)
menu_portapapeles.add_separator()
menu_portapapeles.add_command(label = "Borrar", command = borrar)
menu_portapapeles.add_separator()
menu_portapapeles.add_command(label = "Seleccionar todo", command = seleccionar)


def desplegar_menu(*evento):
    evento = evento[0]
    ventana_x, ventana_y = evento.x_root, evento.y_root
    menu_portapapeles.post(ventana_x, ventana_y)



entrada_datos.bind("<ButtonRelease-3>", desplegar_menu) #capturamos el evento de click derecho

ventana.mainloop()



Ahora explico el siguiente metodo de los Menu:

.delete(1, 2) #este metodo acepta un rango a borrar de comandos sobre el menu, se usa en los programas que tienen un menu como "menu de archivos recientes" para acomodar y borrar del menu los comandos que tengan algun archivo asociado y se descubra que el archivo asiciado no existe mas en disco, su forma de uso tiene unas leyes a seguir:
- el primer numero no puede ser 0 ya que ese numero es el menu mismo que despliega una ventana con el menu. Pero si a la clase Menu le habiamos pasado un booleano al parametro llamado tearoff, por ejemplo si usamos:
Código: You are not allowed to view links. Register or Login
menu_archivo = Menu(ventana, tearoff = False)
... en este ejemplo no tiene en el indice 0 el menu que contiene todos los comandos como una ventana.
- el segundo parametro debe ser un index mas grande que el anterior parametro ejemplo: (1,2), de lo contrario no seria un rango correcto y no borraria nada. Tambien podemos usar el index llamado "end" como cadena en el rango por ejemplo (1, "end"), esto borraria todos los comandos del menu llendo desde el principio al final.


.invoke(1) # este metodo es para invocar el comando que este en el menu y acepta un index, es lo mismo que la accion que se produce cuando usamos el mouse para precionar un comando sobre el menu.



.index(0) # nos devuelve el tipo de comando en el index.


Y ahora hora los ultimos metodos que me queda por hablar con usedes es la diferencia entre add_command y insert_command; estos metodos insertan en un index especifico y no por turno como habiamos hecho anteriormente, podes usar los metodos insert_command, insert_separator, insert_cascade, insert_checkbutton si es que lo requeris por alguna necesidad si es que necesitas ordenar bien el menu.








Saludos y espero que sigan con esto de los menus... hasta la proxima.
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
¡¡¡ORGULLO DE SER ARGENTINOO!!!

Tags:
Tags:

 


SMF 2.0.19 | SMF © 2016, Simple Machines
Paginas Afiliadas
Twitter - FaceBook - Daraxblog
Designed by Smf Personal