Tkinter界面无法调用主代码函数报NameError问题求助
ZPL标签程序跨模块调用报错修复方案
核心问题点
当前代码存在4个直接导致报错和逻辑异常的问题:
- 导入即执行冲突:
classGui.py顶层直接写了根窗口创建、GUI实例化、主循环启动代码,主程序导入ProgGui类时会直接触发这部分逻辑,完全跳过主程序的分支判断 - 命名覆盖冲突:主程序内自定义了空函数
def ProgGui(): pass,和从classGui导入的GUI类重名,会直接覆盖导入的类定义 - 作用域缺失:
classGui.py内未定义、也未导入geraPdf函数,直接引用必然触发NameError;同时GUI类内硬编码引用全局变量app作为控件父容器,没有使用初始化传入的master参数,耦合度极高 - 变量生命周期问题:GUI内存储用户输入的
codInt、quantEtiquetas是__init__方法的局部变量,方法执行完后就会被回收,后续业务逻辑根本拿不到用户输入的值
具体修改方案
1. 重写classGui.py
删除所有顶层执行的启动代码,所有控件父容器统一使用传入的master参数,需要调用的业务函数通过初始化参数注入,输入绑定变量改为实例属性:
from tkinter import * from tkinter import ttk class ProgGui: def __init__(self, master, gera_pdf_func): self.master = master # 绑定传入的PDF生成函数 self.gera_pdf = gera_pdf_func # 输入绑定变量改为实例属性,后续可直接读取用户输入 self.quantEtiquetas = IntVar() self.codInt = IntVar() master.title('Etiquetas') master.geometry('500x200') self.pad = ttk.Frame(master, padding=100) ttk.Label(master, text="Etiquetas").grid(sticky='E') ttk.Label(master, text="Cod do produto").grid(column=0, row=1 ) ttk.Label(master, text="Quant de etiquetas").grid(column=0, row=2) ttk.Entry(master, textvariable=self.codInt).grid(column=1, row=1, padx=20, pady=20) ttk.Entry(master, textvariable=self.quantEtiquetas).grid(column=1, row=2, padx=20, pady=20) ttk.Button(master, text="Quit", command=master.destroy).grid(column=1, row=3) ttk.Button(master, text="Gera Pdf", command=self.gera_pdf).grid(column=0, row=3)
2. 修改主程序文件
删除主程序内空的ProgGui函数定义,调整GUI启动分支逻辑,自行创建Tk根窗口,将geraPdf函数作为参数传入GUI类后再启动主循环:
from ctypes import cast import requests import shutil import sys import csv import os from tkinter import * from classGui import ProgGui modelo_etiqueta_mm =[ [20,35], [30,75], [50,105] ] modelo_etiqueta_in =[ [0.787402,1.37795], [1.1811,2.95276], [1.9685,4.13386] ] dirname = os.path.dirname(__file__) filename = os.path.join(dirname, 'base_produtos.csv') def main_shell(): # 原有命令行执行逻辑 pass def cria_etiqueta(pos_coluna, pos_linha, produto, cod_barra): # 原有标签绘制逻辑 pass def busca_produto(p_cod_produto): # 原有商品查询逻辑 pass def cria_linha(p_qtd_etiqueta,p_cod_produto, p_linhas): # 原有标签行生成逻辑 pass def cria_zpl(p_cod_produto, p_qtd_etiqueta, p_modelo_etiqueta): # 原有ZPL指令生成逻辑 pass def geraPdf(): # 原有PDF生成逻辑,需要读取输入值时可直接通过GUI实例的属性获取 pass if __name__ == '__main__': print(sys.argv) # 命令行模式分支 if len(sys.argv) >= 2: print('Execução de shell.') main_shell() # GUI模式分支 else: print('Execução com Interface') root = Tk() # 传入根窗口和业务函数实例化GUI gui = ProgGui(root, geraPdf) root.mainloop() sys.exit()
开发注意事项
- 所有被导入的模块,不要在顶层写直接执行的业务、界面启动代码,这类逻辑必须放在
if __name__ == '__main__':判断块内,避免导入时自动触发 - 跨模块调用函数优先通过参数传递注入,不要硬编码跨模块引用,避免循环导入问题
- Tkinter开发中不要使用全局变量传递控件、输入值,所有相关对象尽量作为GUI类的实例属性存储,控件父容器统一使用初始化传入的根窗口对象,不要硬编码全局窗口变量
内容的提问来源于stack exchange,提问作者Anderson Silvestre
相关产品推荐
相关产品推荐

