You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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()

关键改动说明

  1. 移除了new_product中无意义的while True循环
  2. 将行号改为持久化存储(全局变量或Frame属性),每次添加产品后自增,确保新控件放在下一行
  3. 补充了原代码缺失的buying函数,避免运行时报错

内容的提问来源于stack exchange,提问作者yacer meftah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 08:15:29