Tkinter按钮用lambda调用外部函数时变量无法返回的问题求助
问题:无法获取外部模块中的文件路径变量
我编写了主文件MMM_LaTeX_PreCleanup.py以及三个功能模块文件TeXImport.py、VadidateMMMModule.py和XMLImport.py。目前遇到两个问题:
- 点击XML浏览按钮后,
XMLFileName变量无法传递到主文件,导致Validate按钮调用时无法使用该变量 - TeX文件的浏览按钮也无法正常触发选择功能
主文件:MMM_LaTeX_PreCleanup.py
import os, sys import re, io from tkinter import * from tkinter import filedialog from tkinter import messagebox ######### Internal Module from XMLImport import OpenXML from TeXImport import OpenTeX from VadidateMMMModule import VadidateMMM ######################################### MMM = Tk() MMM.title("MMM TeX Normalization") MMM.minsize(700,350) ########### XML File Selection Text1 = Label(MMM,text="Please select your Metadata XML") Text1.place(x=10,y=20) XMLFile = Label(MMM,text="XML file was not selected",fg="red") XMLFile.pack() XMLFile.place(x=10,y=45) Browse1 = Button(MMM,text="<Browse>",bg="blue",fg="white",command=lambda: OpenXML(XMLFile)).place(x=220,y=15) ########################################### ############ TeX File Selection Text2 = Label(MMM,text="Please select your TeX file") Text2.place(x=10,y=70) TeXFile = Label(MMM, text="TeX file was not selected",fg="red") TeXFile.pack() TeXFile.place(x=10,y=100) Browse2 = Button(MMM,text="\\Browse", bg="blue",fg="white", command=lambda: OpenTeX(TeXFile)).place(x=180,y=70) ## , font="bold" ##################################################### ########## Output directory Text3 = Label(MMM,text="Please copy/paste your output LOCAL directory on below box") Text3.place(x=10,y=130) name_var = StringVar() MyLocalPath = Entry(MMM, textvariable=name_var, font=('calibre',10,'normal'),width=75) ##MyLocalPath.pack(ipadx=150,ipady=10) MyLocalPath.place(x=10,y=160) ############################################################## ############## Journal List Text4 = Label(MMM,text="Select your Journal name") Text4.place(x=10,y=190) def callback(selection): global GetJournal GetJournal = selection return GetJournal JournalList=StringVar(MMM) JournalList.set("Select your journal") JournalListDrop = OptionMenu(MMM,JournalList, "AA", "BB", "CC", "DD",command=callback) JournalListDrop.pack() JournalListDrop.config(bg="YELLOW") JournalListDrop.place(x=180,y=190) SelectedJournal = JournalList.get() ################################################################## ################ Article Number Text5 = Label(MMM, text="Enter your Article number") Text5.place(x=350,y=190) Art_ID = StringVar() ArticleNo = Entry(MMM,textvariable=Art_ID,font=('calibre',10,'normal'),width=10) ArticleNo.place(x=500,y=190) ####################################################################### ################### Validate, Clear, and Quit button Validate = Button(MMM,text="Validate",bg="green",fg="white",bd=3, command=lambda: VadidateMMM(name_var, Art_ID, GetJournal, XMLFileName )).place(x=10,y=240) ClearAll = Button(MMM,text="Clear",bg="orange",fg="black",bd=3).place(x=90,y=240) Exit = Button(MMM,text="Exit",bg="red",fg="white",bd=3,command=sys.exit).place(x=150,y=240) MMM.mainloop()
XMLImport.py
from tkinter import * from tkinter import filedialog from tkinter import messagebox import io, re, sys, os import shutil def OpenXML(XMLFile): global XMLFileName XMLFileName = filedialog.askopenfilename(initialdir = "/", title="Select your metadata XML file", filetypes=(('XML File','*.xml'),('all file','*.*'))) XMLFile.configure(text="XML File selected: "+XMLFileName,fg='green') return XMLFileName
TeXImport.py
def OpenTeX(TeXFile): global TeXFileName TeXFileName = filedialog.askopenfilename(initialdir = "/", title="Select your TeX file", filetypes=(('TeX File','*.tex'),('all file','*.*'))) TeXFile.configure(text="TeX File selected: "+TeXFileName,fg='green') return TeXFileName
VadidateMMMModule.py
import os, sys from tkinter import messagebox import shutil def VadidateMMM(name_var,Art_ID,GetJournal,XMLFileName): MyLocalPath = name_var.get() #### Validating it was only be a local path if not MyLocalPath.startswith(("D:","E:","F:","G:","H:")): messagebox.showinfo("__file__","Your are set output to local path. Hence i quit") sys.exit() ############################################ MyArticleNumber = Art_ID.get() MyJournal = GetJournal ###### Creating the Folder os.chdir(MyLocalPath) os.mkdir(MyJournal+"-"+MyArticleNumber) ###### Copying the XML file shutil.copy(XMLFileName,MyLocalPath)
修复方案
1. 重构子模块函数,去掉跨模块全局变量
子模块不需要定义全局变量,直接返回选中的文件路径即可:
- 修改
XMLImport.py:
from tkinter import filedialog from tkinter import messagebox def OpenXML(XMLFile): xml_path = filedialog.askopenfilename(initialdir="/", title="Select your metadata XML file", filetypes=(('XML File','*.xml'),('all file','*.*'))) if xml_path: XMLFile.configure(text=f"XML File selected: {xml_path}", fg='green') else: XMLFile.configure(text="XML file was not selected", fg='red') return xml_path
- 修改
TeXImport.py:
from tkinter import filedialog from tkinter import messagebox def OpenTeX(TeXFile): tex_path = filedialog.askopenfilename(initialdir="/", title="Select your TeX file", filetypes=(('TeX File','*.tex'),('all file','*.*'))) if tex_path: TeXFile.configure(text=f"TeX File selected: {tex_path}", fg='green') else: TeXFile.configure(text="TeX file was not selected", fg='red') return tex_path
2. 主文件中统一管理全局变量
在主文件开头定义全局变量存储路径,修改按钮命令直接接收返回值:
# 导入模块后添加全局变量初始化 XMLFileName = "" TeXFileName = "" GetJournal = "" # 修改XML浏览按钮命令 Browse1 = Button(MMM, text="<Browse>", bg="blue", fg="white", command=lambda: globals().update(XMLFileName=OpenXML(XMLFile))).place(x=220,y=15) # 修改TeX浏览按钮命令,同时修正文本显示问题 Browse2 = Button(MMM, text="<Browse>", bg="blue", fg="white", command=lambda: globals().update(TeXFileName=OpenTeX(TeXFile))).place(x=180,y=70)
3. 完善Validate函数的参数与校验
更新VadidateMMMModule.py,添加空值检查与异常处理:
import os, sys from tkinter import messagebox import shutil def VadidateMMM(name_var, Art_ID, GetJournal, XMLFileName, TeXFileName): MyLocalPath = name_var.get() # 前置校验:检查所有必填项 if not XMLFileName: messagebox.showwarning("Warning", "请先选择XML文件!") return if not TeXFileName: messagebox.showwarning("Warning", "请先选择TeX文件!") return if not MyLocalPath: messagebox.showwarning("Warning", "请输入输出目录!") return if not GetJournal: messagebox.showwarning("Warning", "请选择期刊名称!") return if not Art_ID.get(): messagebox.showwarning("Warning", "请输入文章编号!") return # 本地路径验证 if not MyLocalPath.startswith(("D:","E:","F:","G:","H:")): messagebox.showinfo("提示", "输出路径必须是本地磁盘(D:/、E:/等)") return MyArticleNumber = Art_ID.get() MyJournal = GetJournal target_folder = os.path.join(MyLocalPath, f"{MyJournal}-{MyArticleNumber}") try: # 创建文件夹(已存在则跳过) os.makedirs(target_folder, exist_ok=True) # 复制文件到目标文件夹 shutil.copy(XMLFileName, target_folder) shutil.copy(TeXFileName, target_folder) messagebox.showinfo("成功", "文件处理并复制完成!") except Exception as e: messagebox.showerror("错误", f"文件处理失败:{str(e)}")
最后修改主文件中Validate按钮的命令,传入TeXFileName参数:
Validate = Button(MMM,text="Validate",bg="green",fg="white",bd=3, command=lambda: VadidateMMM(name_var, Art_ID, GetJournal, XMLFileName, TeXFileName )).place(x=10,y=240)
内容的提问来源于stack exchange,提问作者Srinivasan Ganapathy
相关产品推荐
相关产品推荐

