Custom Tkinter使用pack_forget后出现重复添加按钮问题求助
问题分析
问题出在你每次调用loadSelectionFrame时,只是通过pack_forget隐藏了selectionFrame,但Frame内部的旧控件(包括之前的加号按钮)并没有被移除。当你再次调用loadSelectionFrame时,会在同一个Frame里新增一套标签、组合框和按钮,旧的按钮仍然存在,因此会出现两个加号按钮。
解决方案
方法一:清空Frame后再加载新控件
在loadSelectionFrame函数开头,先遍历selectionFrame的所有子控件并销毁它们,确保每次加载都是全新的控件:
修改后的完整代码:
import customtkinter import tkinter customtkinter.set_appearance_mode('dark') customtkinter.set_default_color_theme('dark-blue') #dark-blue, blue, or green def loadSelectionFrame(buttonCount=1): # 先清空selectionFrame内的所有旧控件 for widget in selectionFrame.winfo_children(): widget.destroy() selectionFrame.rowconfigure(buttonCount+2, weight=1) selectionFrame.columnconfigure(2, weight=1) selectionFrame.pack() fieldLabel = customtkinter.CTkLabel(master=selectionFrame, text="Choose Field") fieldLabel.grid(row=1, column=1, pady=12, padx=10) typeLabel = customtkinter.CTkLabel(master=selectionFrame, text="Choose Value") typeLabel.grid(row=1, column=2, pady=12, padx=10) for i in range(buttonCount): fieldsDropDown = customtkinter.CTkComboBox(master=selectionFrame, values=["Option 1", "Option 2"]) fieldsDropDown.grid(row=i+2, column=1, pady=12, padx=10) typeDropDown = customtkinter.CTkComboBox(master=selectionFrame, values=["Option 1", "Option 2"]) typeDropDown.grid(row=i+2, column=2, pady=12, padx=10) addMoreFieldsButton = customtkinter.CTkButton(master=selectionFrame, text="+", command=lambda: addMoreFields(buttonCount+1, selectionFrame)) addMoreFieldsButton.grid(row=buttonCount+2, columnspan=3, pady=12, padx=10) def addMoreFields(buttonCount, selectionFrame): selectionFrame.pack_forget() loadSelectionFrame(buttonCount) root = customtkinter.CTk() mainFrame = customtkinter.CTkFrame(master=root) mainFrame.pack(pady=20,padx=60, fill='both', expand=True) selectionFrame = customtkinter.CTkFrame(master=mainFrame) loadSelectionFrame() root.mainloop()
方法二:直接新增组合框(更高效)
不需要每次销毁重建所有控件,只需要在点击按钮时新增一行组合框,并调整按钮的位置:
修改后的代码:
import customtkinter import tkinter customtkinter.set_appearance_mode('dark') customtkinter.set_default_color_theme('dark-blue') #dark-blue, blue, or green current_row = 2 # 记录当前要新增组合框的行号 add_button = None # 保存加号按钮的引用 def loadSelectionFrame(): global current_row, add_button selectionFrame.rowconfigure(0, weight=1) selectionFrame.columnconfigure(2, weight=1) selectionFrame.pack() fieldLabel = customtkinter.CTkLabel(master=selectionFrame, text="Choose Field") fieldLabel.grid(row=1, column=1, pady=12, padx=10) typeLabel = customtkinter.CTkLabel(master=selectionFrame, text="Choose Value") typeLabel.grid(row=1, column=2, pady=12, padx=10) # 初始化第一行组合框 fieldsDropDown = customtkinter.CTkComboBox(master=selectionFrame, values=["Option 1", "Option 2"]) fieldsDropDown.grid(row=current_row, column=1, pady=12, padx=10) typeDropDown = customtkinter.CTkComboBox(master=selectionFrame, values=["Option 1", "Option 2"]) typeDropDown.grid(row=current_row, column=2, pady=12, padx=10) current_row +=1 # 创建加号按钮 add_button = customtkinter.CTkButton(master=selectionFrame, text="+", command=addMoreFields) add_button.grid(row=current_row, columnspan=3, pady=12, padx=10) def addMoreFields(): global current_row, add_button # 新增一行组合框 fieldsDropDown = customtkinter.CTkComboBox(master=selectionFrame, values=["Option 1", "Option 2"]) fieldsDropDown.grid(row=current_row, column=1, pady=12, padx=10) typeDropDown = customtkinter.CTkComboBox(master=selectionFrame, values=["Option 1", "Option 2"]) typeDropDown.grid(row=current_row, column=2, pady=12, padx=10) current_row +=1 # 调整加号按钮的位置到新的行 add_button.grid(row=current_row, columnspan=3, pady=12, padx=10) root = customtkinter.CTk() mainFrame = customtkinter.CTkFrame(master=root) mainFrame.pack(pady=20,padx=60, fill='both', expand=True) selectionFrame = customtkinter.CTkFrame(master=mainFrame) loadSelectionFrame() root.mainloop()
说明
- 方法一通过
widget.destroy()彻底删除旧控件,确保每次加载都是全新的内容,适合简单场景。 - 方法二更高效,只新增需要的控件,避免重复创建标签和销毁控件,适合频繁添加的场景。
内容的提问来源于stack exchange,提问作者Dorian
相关产品推荐
相关产品推荐

