Tkinter开发中如何实现按钮点击使用后隐藏
问题根因
yes按钮无法隐藏是代码逻辑缺陷导致的,具体问题如下:
yes按钮定义在findchild()函数内部,属于局部变量,其他函数(比如你写的noBot)根本访问不到这个按钮对象,自然没法调用隐藏方法- 你只在查询不到孩子时才创建、显示yes按钮,但在「查询到孩子存在」「点击no按钮拒绝新增」「点击yes完成新增」这三个需要隐藏按钮的场景,完全没写隐藏yes按钮的逻辑
- 每次触发查询不到的逻辑都会重复新建一个yes按钮堆在界面上,哪怕之前的按钮没隐藏,新按钮又会盖上去,永远清不干净
- 附带两个影响功能的逻辑bug:一是遍历Excel行判断孩子是否存在时,只要第一行不匹配就会标记为不存在,哪怕后面行有匹配数据也会误判;二是
yesBot里修改的是函数内部的局部DataFrame,不会更新全局读取的Excel数据,新增完孩子下次查询还是找不到。
修复方案
- 把
yes按钮和其他全局控件(nobot、askMan)一块在全局位置初始化,初始状态设置为隐藏,不要在findchild函数里重复新建按钮 - 补全所有场景的控件显隐逻辑:需要提示新增时显示三个控件,其余场景全部调用
grid_forget()隐藏 - 修复遍历判断的逻辑:先默认标记孩子不存在,遍历完全部行只要找到匹配项就标记为存在并终止遍历
- 修复DataFrame全局变量更新的问题,新增孩子后同步更新全局变量,避免下次查询读旧数据
修复后可直接运行的代码
import pandas as pd from tkinter import * import tkinter.messagebox root=Tk() ChildGym = pd.read_excel('TheGloriousEvolution.xlsx') def findchild(): #check if child is inside excel file firstNameLabel1=firstNameEntry.get() secNameLabel1=secNameEntry.get() # 先默认标记为找到(不触发新增提示) answer = True # 优先判断输入是否为空 if not firstNameLabel1: ans.configure(text="pls enter child first name") elif not secNameLabel1: ans.configure(text="pls enter child sec name ") else: # 输入合法时先标记为未找到,遍历所有行匹配 answer = False for index, row in ChildGym.iterrows(): if row['FirstName']==firstNameLabel1 and row['SecName']==secNameLabel1: ans.configure(text="all good!") answer=True break # 遍历完所有行没找到才提示不存在 if not answer: ans.configure(text="the kid is not here") # 根据查找结果控制新增相关控件显隐 if answer==False: # 没找到就显示询问文本和两个按钮 askMan.grid(row=4,column=2) nobot.grid(row=4,column=3) yes.grid(row=4,column=4) else: # 找到/输入为空就隐藏所有新增相关控件,清空提示 askMan.grid_forget() nobot.grid_forget() yes.grid_forget() ans2.configure(text="") def yesBot(firstNameLabel1,secNameLabel1): # 声明修改全局的ChildGym变量,避免局部变量覆盖 global ChildGym ChildGym_new_row = pd.DataFrame({ 'FirstName': [firstNameLabel1], 'SecName': [secNameLabel1] }) ChildGym=pd.concat([ChildGym,ChildGym_new_row], axis=0, ignore_index=True) ans2.configure(text="kid got added succesfully!") ChildGym.to_excel("TheGloriousEvolution.xlsx", index=False) # 新增完成后隐藏新增相关控件,清空输入框 askMan.grid_forget() nobot.grid_forget() yes.grid_forget() firstNameEntry.delete(0, END) secNameEntry.delete(0, END) def noBot(): # 点no的时候把三个新增相关控件全部隐藏,清空提示 askMan.grid_forget() nobot.grid_forget() yes.grid_forget() ans2.configure(text="") # 查找触发按钮 Bot=Button(root,text="click me",command=findchild) Bot.grid(row=0,column=4) # 新增询问文本 askMan=Label(text="do you want to add this child?") # 拒绝新增按钮 nobot=Button(root,text="no",command=noBot) # 确认新增按钮,全局初始化,默认不显示 yes=Button(root,text="yes",command=lambda: yesBot(firstNameEntry.get(),secNameEntry.get())) # 名字输入区域 firstNameLabel=Label(text="what is the first name of the kid you want to search?") firstNameLabel.grid(row=0,column=0) firstNameEntry=Entry(root) firstNameEntry.grid(row=0,column=1) # 查询结果提示 ans=Label(root) ans.grid(row=0,column=2) # 新增结果提示 ans2=Label(root) ans2.grid(row=4,column=1) # 姓氏输入区域 secNameLabel=Label(text="what is the sec name of the kid you want to search?") secNameLabel.grid(row=1,column=0) secNameEntry=Entry(root) secNameEntry.grid(row=1,column=1) root.mainloop()
内容的提问来源于stack exchange,提问作者Maklonim
相关产品推荐
相关产品推荐

