Tkinter中'Toplevel'对象不可调用错误排查求助
解决Tkinter窗口关闭后再次打开报错TypeError: 'Toplevel' object is not callable
问题核心是全局变量命名冲突:
在openContractWindow函数中,你声明了global contractWindow,随后将contractTk.Toplevel(...)赋值给了这个变量。但contractWindow本身是你定义的函数名,这导致第一次调用后,原本的contractWindow函数被覆盖成了Toplevel对象。第二次再尝试调用contractData.contractWindow(...)时,实际上是在调用一个Toplevel对象,自然会抛出'Toplevel' object is not callable的错误。
修复方案
重命名全局窗口变量,避免和函数名重复,同时在所有用到该变量的地方统一替换:
修改后的theData/contracts.py代码如下:
openContractFlag = False def contractWindow(contractRoot, contractTk, contractHeight, contractWidth): global openContractFlag contractWidth = int((contractWidth/2) - 600) contractHeight = int((contractHeight/2) - 500) if openContractFlag == False: openContractFlag = True openContractWindow(contractRoot, contractTk, contractWidth, contractHeight) def openContractWindow(contractRoot, contractTk, contractWidth, contractHeight): # 重命名全局变量为contract_win,避免和函数名contractWindow冲突 global contract_win contract_win = contractTk.Toplevel(contractRoot) contract_win.title("Overenskomster") contract_win.geometry(f"900x800+{contractWidth}+{contractHeight}") # 创建新窗口内的按钮 contractCloseButton = contractTk.Button(contract_win, text="Luk", command=contractClose, bg="blue", fg="white", font=("Helvetica", 16, "bold")) contractCloseButton.place(x=100, y= 10) newContract = contractTk.Button(contract_win, text="Opret ny overenskomst", command=makeNewContract, bg="blue", fg="white", font=("Helvetica", 16, "bold")) newContract.place(x=200, y= 10) label = contractTk.Label(contract_win, text="En liste med alle overenskomster", borderwidth=2, bg="black", fg="white", font=("Helvetica", 16, "bold")) label.place(x=270, y=70) def contractClose(): global openContractFlag, contract_win if contract_win is not None: openContractFlag = False contract_win.destroy() # 可选:销毁后将变量置为None,避免引用已销毁的对象 contract_win = None def makeNewContract(): print("Make new contract")
关键修改点
- 将全局窗口变量从
contractWindow改为contract_win,彻底避免和函数名的冲突 - 在
contractClose函数中新增contract_win的全局声明,并在销毁窗口后可选将其置为None,防止后续误操作
修改完成后,第二次调用contractData.contractWindow(...)时,调用的依然是原本的函数,不会再触发类型错误。
内容的提问来源于stack exchange,提问作者Lars
相关产品推荐
相关产品推荐

