Tkinter 的嵌套窗口中未定义变量

问题描述 投票:0回答:2

我正在用 Python 和 Tkinter(python 版本 3.11.3 和 Spyder)制作 GUI。

GUI 用于控制某种机器(类似于日志文件,但更简单)。 在根窗口(ventana principal)中,当我单击“不可接受”(boton_flujo_2)时,另一个窗口打开了 Toplevel(称为“Ventana 1”)。在该窗口中,我希望如果选中“No necesario 2”,则应禁用该窗口中的按钮。 我在“Ventana principal”中使用相同的逻辑并且它有效但是当我想在“Ventana 1”中使用时我有下一个错误:

"NameError: name 'mensual_check_top1' is not defined"

我的代码是下一个:

import tkinter as tk
from tkinter import ttk 

#Para deshabilitar widgets segun ciertas condiciones    
def disable_widgets():
    # disable dropdown menu si Valve Status "0 (cero)" esta checkeado
    if cero_check.get() == 1:
        dropdown.config(state='disabled')
    else:
        dropdown.config(state='readonly')

  # disable flujo box si "5lpm" esta checkeado
    if flow_check.instate(['selected']):
        flow_entry.config(state='disabled')
    else:
        flow_entry.config(state='normal')
        
  # disable boton_flujo widget en CONTROL MENSUAL si "no necesario" esta checkeado
    if control_mensual_check.instate(['selected']):
        boton_flujo_1.config(state='disabled')
        boton_flujo_2.config(state='disabled')
        #boton_flujo_3.config(state='disabled')
        #boton_flujo_4.config(stapte='disabled')
    else:
        boton_flujo_1.config(state='normal')
        boton_flujo_2.config(state='normal')
       # boton_flujo_3.config(state='normal')
       # boton_flujo_4.config(state='normal')
         
  # disable boton_flujo widget en Ventana 1 si "No necesario 2" esta checked
    if mensual_check_top1.instate(['selected']):
        boton_flujo_3.config(state='disabled')
        boton_flujo_4.config(state='disabled')
    else:
        boton_flujo_3.config(state='normal')
        boton_flujo_4.config(state='normal')
        
#Para que Status solo admita numeros
def validate_numeric_input(new_value):
    return new_value.isnumeric()

#Ventana 1
def realizar_calibracion():
    
 
    ventana1 = tk.Toplevel(root)
    ventana1.geometry("300x100")
    ventana1.title("Ventana 1")

    verif_flujo_mensual = ttk.Label(ventana1, text="Verificacion de flujo")
    verif_flujo_mensual.grid(row=0, column=1)
    
    mensual_check_top1 = ttk.Checkbutton(ventana1, text="No necesario 2", command=disable_widgets)
    mensual_check_top1.grid(row=2, column=0)

    boton_flujo_3 = ttk.Button(ventana1, text="Aceptable")
    boton_flujo_3.grid(row=2, column=1)

    boton_flujo_4 = ttk.Button(ventana1, text="No aceptable")#,command=realizar_calibracion)
    boton_flujo_4.grid(row=2, column=2)
    

#Ventana Principal (root)
root = tk.Tk()
root.title("Ventana Principal") 
root.geometry("800x600")

# OPERADOR
operador_label = ttk.Label(root, text="Operador")
operador_label.grid(row=0, column=0)
operador_entry = ttk.Entry(root)
operador_entry.grid(row=0, column=1)

# STATUS. VALIDO INGRESO SOLO DE NUMEROS
status_label = ttk.Label(root, text="Status")
status_label.grid(row=1, column=0)
status_entry = ttk.Entry(root, validate="key")
status_entry['validatecommand'] = (status_entry.register(validate_numeric_input), '%P')
status_entry.grid(row=1, column=1)

# VALVE STATUS
valve_status_label = ttk.Label(root, text="Valve Status")
valve_status_label.grid(row=2, column=0)

    # si 0 cero check, desplegable deshabilitado 
cero_check = tk.IntVar()
cero_checkbox = ttk.Checkbutton(root, text="0 (cero)", variable=cero_check, command=disable_widgets)
cero_checkbox.grid(row=2, column=1)

    # desplegable para opciones de Valve Status que no son cero
options_var = tk.StringVar()
options = [" Otro valor ","01011 : Derivación", "01100 : Calentamiento/Aire limpio", "00000 : Medida", "00010 : Calibración medidor de flujo"]
dropdown = ttk.OptionMenu(root, options_var, *options)
dropdown.grid(row=2, column=2)

# APARIENCIA DEL FILTRO CON DESPLEGABLE
apariencia_filtro_label = ttk.Label(root, text="Apariencia Filtro")
apariencia_filtro_label.grid(row=3, column=0)

apariencia_filtro_options = ["APARIENCIA","Normal", "Achucharrado", "Marron"]
apariencia_filtro_var = tk.StringVar(value="")
apariencia_filtro_dropdown = ttk.OptionMenu(root, apariencia_filtro_var, *apariencia_filtro_options)
apariencia_filtro_dropdown.grid(row=3, column=1)

# FLUJO. 
flow_label = ttk.Label(root, text="Flujo")
flow_label.grid(row=4, column=0)
    # si 5lpm checkeado, deshabilito blank box
flow_check = ttk.Checkbutton(root, text="5lpm", command=disable_widgets)
flow_check.grid(row=4, column=1)
    #blank box
flow_entry = ttk.Entry(root)
flow_entry.grid(row=4, column=2)

# CINTA REEMPLAZADA
replacement_tape_label = ttk.Label(root, text="Cinta reemplazada?")
replacement_tape_label.grid(row=5, column=0)

    #checkbutton para cinta reemplazada
replacement_tape_check = ttk.Checkbutton(root, text="Si")
replacement_tape_check.grid(row=5, column=1)


# DIVISION
division_label = ttk.Label(root, text="------------------------------")
division_label.grid(row=7, column=1)


# TITULO CHECKLIST GENERAL
general_label = ttk.Label(root, text="CHECKLIST GENERAL")
general_label.grid(row=8, column=1)


# CHECKLIST GENERAL
big_checkbox_var = tk.IntVar()
big_checkbox = ttk.Checkbutton(root, width=0)
big_checkbox.grid(row=9, column=1, rowspan=4)

    # Hora actual + hora instrumento
hora_label = ttk.Label(root, text="Chequeo hora actual + instrumento")
hora_label.grid(row=9, column=0)


    # Inspeccion caño y manguera
mangueras_label = ttk.Label(root, text="Inspeccion caños y mangueras")
mangueras_label.grid(row=10, column=0)


    # Trampa agua interna
aguainterna_label = ttk.Label(root, text="Inspeccion trampa de agua interna")
aguainterna_label.grid(row=11, column=0)

    # Trampa agua externa
aguaexterna_label = ttk.Label(root, text="Inspeccion trampa de agua externa")
aguaexterna_label.grid(row=12, column=0)

# DIVISION
division_label = ttk.Label(root, text="------------------------------")
division_label.grid(row=13, column=1)

# CONTROL MENSUAL
general_label = ttk.Label(root, text="CONTROL MENSUAL")
general_label.grid(row=14, column=1) 

# create label for mangueras
verif_flujo = ttk.Label(root, text="Verificacion de flujo")
verif_flujo.grid(row=15, column=0)

control_mensual_check = ttk.Checkbutton(root, text="No necesario", command=disable_widgets)
control_mensual_check.grid(row=15, column=1)

boton_flujo_1 = ttk.Button(root, text="Aceptable")
boton_flujo_1.grid(row=15, column=2)

boton_flujo_2 = ttk.Button(root, text="No aceptable",command=realizar_calibracion)
boton_flujo_2.grid(row=15, column=3)


root.mainloop()

提前谢谢你!

问问

我在“Ventana principal”中使用相同的逻辑并且它有效但是当我想在“Ventana 1”中使用时我有下一个错误:

"NameError: name 'mensual_check_top1' is not defined"
.

我也试过制作全局变量,但都没有用。

python user-interface tkinter spyder
2个回答
0
投票

我能够使用您提供的代码重现您的问题。我相信我也能够解决您提到的问题以获得您想要的结果。

“Ventana 1”代码的主要问题是所有变量都在一个函数中分类,而“Ventana principal”则不是这样。这就是它给您“未定义”错误的原因。要解决此问题,您只需将变量设置为全局变量,以便可以在

disable_widgets
函数中使用它们。以下是我为使其正常工作所做的更改。

#Ventana 1
def realizar_calibracion():

    ventana1 = tk.Toplevel(root)
    ventana1.geometry("300x100")
    ventana1.title("Ventana 1")

    verif_flujo_mensual = ttk.Label(ventana1, text="Verificacion de flujo")
    verif_flujo_mensual.grid(row=0, column=1)
 
    global mensual_check_top1 
    mensual_check_top1 = ttk.Checkbutton(ventana1, text="No necesario 2", command=disable_widgets)
    mensual_check_top1.grid(row=2, column=0)

    global boton_flujo_3
    boton_flujo_3 = ttk.Button(ventana1, text="Aceptable")
    boton_flujo_3.grid(row=2, column=1)

    global boton_flujo_4
    boton_flujo_4 = ttk.Button(ventana1, text="No aceptable")#,command=realizar_calibracion)
    boton_flujo_4.grid(row=2, column=2)

如您所见,我刚刚制作了

mensual_check_top1
boton_flujo_3
boton_flujo_4
所有全局变量,以便可以从
realizar_calibracion
函数外部使用它们。


0
投票

我相信如果

mensual_check_top1
是在
realizar_calibracion()
函数之外创建的,那么这个错误是可以避免的。

尝试将创建 Checkbutton 的行(如下所示)移到函数之外。您可以将

.grid()
命令留在函数内,以便在执行函数之前不会出现按钮。

mensual_check_top1 = ttk.Checkbutton(ventana1, text="No necesario 2", command=disable_widgets)

编辑: 也将

ventana1
和其他必要的小部件的定义移到函数之外。因此,您的小部件和窗口是在函数之外定义的,并在函数内部配置/打包。这避免了使用
global
.

© www.soinside.com 2019 - 2024. All rights reserved.