如何用Tkinter实现点击按钮每次在下方新增一行对象
修复Tkinter中点击“new product”只能添加一个产品的问题
问题根源
你的new_product函数每次被调用时,都会把row重新初始化为1,然后自增到2,所以每次新创建的产品都会被放在第2行,导致所有新控件叠加在一起。另外原函数里的while True循环完全多余,只执行一次就break,没有实际作用。
修复方案
需要让row的值在多次调用new_product时保持持久化,不会每次重置。这里提供两种实用方法:
方法1:使用全局变量跟踪行号
把行号定义为全局变量,每次添加产品后更新它的值:
from tkinter import * screen = Tk() screen.title("Buyer") screen.geometry("800x600") w = Frame(screen) w.grid(padx=1, pady=1) w.pack(pady=5) # 初始化全局行号,从2开始(第0行放功能按钮) current_row = 2 class product: def __init__(self, image, name, price, quantity, save): self.image = image self.name = name self.price = price self.quantity = quantity self.save = save def product_row(self, row): # 原代码中Add_image、create_item未定义,保留原结构 self.image.configure(command=lambda: Add_image(self.image, row)) self.save.configure(command=lambda: create_item(self.name, self.price)) self.image.grid(column=0, row=row, padx=30, pady=15) self.name.grid(column=1, row=row, padx=30, pady=15) self.price.grid(column=2, row=row, padx=30, pady=15) self.quantity.grid(column=3, row=row, padx=30, pady=15) self.save.grid(column=4, row=row, padx=30, pady=15) def create_product(): add_image = Button(w, text="+", font=("helvetica", 30)) add_name = Entry(w, font=("helvetica", 13)) add_price = Entry(w, font=("helvetica", 16), width=5) add_quantity = Entry(w, font=("helvetica", 16), width=5) save = Button(w, text="save item", font=("helvetica", 13)) return product(add_image, add_name, add_price, add_quantity, save) def new_product(): global current_row prd = create_product() prd.product_row(row=current_row) current_row += 1 # 每次添加后行号自增 def selling(): buying_button.destroy() selling_button.destroy() screen.title("selling mode") Button(w, text="switch", command=buying).grid(row=0, column=2, pady=15, padx=30) Button(w, text="new product", command=new_product).grid(row=0, column=1, pady=15, padx=30) # 补充原代码未定义的buying函数,避免报错 def buying(): pass buying_button = Button(w, text="buyer mode", font=("helvetica", 16), width=16, height=2) selling_button = Button(w, text="seller mode", font=("helvetica", 16), width=16, height=2, command=selling) selling_button.pack() buying_button.pack() screen.mainloop()
方法2:用Frame属性存储行号(更优雅,避免全局变量)
把当前行号绑定到承载控件的Frame对象上,不需要额外全局变量:
from tkinter import * screen = Tk() screen.title("Buyer") screen.geometry("800x600") w = Frame(screen) w.grid(padx=1, pady=1) w.pack(pady=5) # 给Frame添加属性跟踪当前行号 w.current_row = 2 class product: def __init__(self, image, name, price, quantity, save): self.image = image self.name = name self.price = price self.quantity = quantity self.save = save def product_row(self, row): self.image.configure(command=lambda: Add_image(self.image, row)) self.save.configure(command=lambda: create_item(self.name, self.price)) self.image.grid(column=0, row=row, padx=30, pady=15) self.name.grid(column=1, row=row, padx=30, pady=15) self.price.grid(column=2, row=row, padx=30, pady=15) self.quantity.grid(column=3, row=row, padx=30, pady=15) self.save.grid(column=4, row=row, padx=30, pady=15) def create_product(): add_image = Button(w, text="+", font=("helvetica", 30)) add_name = Entry(w, font=("helvetica", 13)) add_price = Entry(w, font=("helvetica", 16), width=5) add_quantity = Entry(w, font=("helvetica", 16), width=5) save = Button(w, text="save item", font=("helvetica", 13)) return product(add_image, add_name, add_price, add_quantity, save) def new_product(): prd = create_product() prd.product_row(row=w.current_row) w.current_row += 1 def selling(): buying_button.destroy() selling_button.destroy() screen.title("selling mode") Button(w, text="switch", command=buying).grid(row=0, column=2, pady=15, padx=30) Button(w, text="new product", command=new_product).grid(row=0, column=1, pady=15, padx=30) def buying(): pass buying_button = Button(w, text="buyer mode", font=("helvetica", 16), width=16, height=2) selling_button = Button(w, text="seller mode", font=("helvetica", 16), width=16, height=2, command=selling) selling_button.pack() buying_button.pack() screen.mainloop()
关键改动说明
- 移除了
new_product中无意义的while True循环 - 将行号改为持久化存储(全局变量或Frame属性),每次添加产品后自增,确保新控件放在下一行
- 补充了原代码缺失的
buying函数,避免运行时报错
内容的提问来源于stack exchange,提问作者yacer meftah
相关产品推荐
相关产品推荐

