es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Intentando pasar una función de Python almacenada en una base de datos SQL a un menú en TKinter.

Estoy escribiendo una aplicación en python usando tkinter como el framework de GUI. Estoy guardando los comandos de menú en listas en una tabla SQL y estoy iterando a través de todas las filas seleccionadas para construir el menú. Hasta ahora esto funciona bien, pero no puedo hacer que el comando funcione cuando se hace clic en el elemento del menú. La tabla SQL tiene 4 columnas ID, Etiqueta, Comando, Padre. Entonces, un ejemplo de fila para la tabla se vería así:

1, Nuevo, placeholder(), rootFile

Cuando hago clic en el comando “Nuevo”, no sucede nada. Si reemplazo row[2] con placeholder(), funciona como se espera, desafortunadamente esto no me permite especificar diferentes comandos para cada elemento de menú almacenado en la base de datos SQL.

import pyodbc # necesario para la conectividad con la base de datos
from tkinter import * # importa los objetos de GUI
from tkinter import ttk # importa widgets temáticos para GUI
from database_connect import SQL_CONNECT

setupSQL = SQL_CONNECT('Server=MILLER2021;Database=DRAWINGTOOLDB;') # establece la conexión con la base de datos SQL que contiene la información de inicio para la aplicación
setupCursor = setupSQL.cursor() # crea un objeto cursor para la conexión SQL para configurar la aplicación

root = Tk() # crea un widget de ventana de nivel superior
root.title("Drawing Tool") # define el título de root
root.geometry("400x300") # define el tamaño de root

def placeholder():
    print("Este es una salida de la función de relleno")

# Define la barra de menú
rootMenuBar = Menu(root)
rootFile = Menu(rootMenuBar, tearoff=0)
rootMenuBar.add_cascade(label="Archivo", menu=rootFile)    # muestra el elemento en el menú
setupCursor.execute("SELECT * FROM MENU_COMMANDS WHERE PARENT LIKE 'rootFile'") # selecciona todos los comandos de la base de datos SQL para agregarlos al menú rootFile
for row in setupCursor: # itera a través de todas las filas seleccionadas de la consulta anterior del cursor
    rootFile.add_command(label=row[1], command=row[2]) # agrega un nuevo elemento al menú de archivo
root.config(menu=rootMenuBar) # muestra la barra de menú en el menú root
root.mainloop() # mantiene el código en ejecución
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema en el código dado parece estar en el parámetro “command” del método add_command. En lugar de pasar el objeto función, se está pasando el valor de la columna “command” de la tabla SQL como una cadena de caracteres. Esto significa que cuando se hace clic en el elemento del menú, trata de ejecutar la cadena como una función, lo cual resulta en un error.

    Para solucionar este problema, el valor de la columna “command” debe evaluarse como un objeto función antes de pasarlo al método add_command. Esto se puede hacer utilizando la función eval(). Sin embargo, es importante tener en cuenta que el uso de eval() puede ser peligroso si los valores en la columna “command” no son seguros, ya que permite la ejecución de código arbitrario.

    Una posible solución a este problema es modificar el bucle que itera a través de las filas de la tabla SQL de la siguiente manera:

    for row in setupCursor:
        command = eval(row[2])
        rootFile.add_command(label=row[1], command=command)
    

    Esto evaluará el valor de la columna “command” como un objeto función y lo pasará como parámetro “command” al método add_command, lo cual debería permitir que los elementos del menú funcionen como se espera.

Comments are closed.