首页 > 解决方案 > 如何检测按下哪个按钮来调用特定于它的命令?

问题描述

我正在尝试制作一个自动售货机 UI,它有 25 个使用此代码动态生成的按钮:

    def retrieve_tiem(): #SQL query to reteive item into Item_List[]

    ROWS = COLS = 5
    MAX_ITEMS = ROWS * COLS
    frames = []
    for i in range(MAX_ITEMS):
        frames.append(Frame(store_canvas, width=1520 / COLS, height=1030 / ROWS, bd=2, relief=SOLID))
        frames[-1].grid(row=i // COLS, column=i % COLS)
        frames[-1].pack_propagate(False)

    def update_list():
        label_font = ("Arial", 15)
        for i,frame in enumerate(frames):
            for w in frame.winfo_children():
                w.destroy()
            if i < len(Item_list):
                item = Item_list[i]
                Button(frame).pack(fill="both", expand=1)
                Label(frame, text=Item_list[i], font=label_font, bg="darkgreen", fg="yellow").pack(fill="x")

我如何获得此代码及其背景的上下文在这里。我希望能够使用该按钮来调用顶级小部件以显示与该按钮相对应的正确待售商品。但是,此代码生成的网格将根据用户选择的过滤器选项动态减少或增加。这意味着没有按钮可以保持每次调用的相同“ID”。我先上网查了一下,发现这个有点类似的问题。唯一的缺点是该帖子中的按钮是固定的,不能四处移动。有没有办法让我达到上述效果?另外关于类似的链接帖子,它可能对我有用,但我只是碰巧在逻辑上分析错了吗?非常感谢所有答案。

编辑:对于那些想要快速复制结果的人,当项目数量根据过滤器增加或减少时,按钮的行为方式,这里是代码:

from tkinter import *
import random

root = Tk()

store_canvas = Frame(root)
store_canvas.pack()

# create the 25 frames
ROWS = COLS = 5
MAX_ITEMS = ROWS * COLS
frames = []
for i in range(MAX_ITEMS):
    frames.append(Frame(store_canvas, width=1520/COLS, height=1030/ROWS, bd=2, relief=SOLID))
    frames[-1].grid(row=i//COLS, column=i%COLS)
    frames[-1].pack_propagate(False)

# function to simulate retrieving data from database table
def retrieve_tiem():
    return [f"Item #{i+1}" for i in range(random.randint(1,MAX_ITEMS))]

# function to show the retrieved items
def update_list():
    Item_list = retrieve_tiem()
    label_font = ("Arial", 20)
    for i, frame in enumerate(frames):
        for w in frame.winfo_children():
            w.destroy()
        if i < len(Item_list):
            item = Item_list[i]
            Button(frame).pack(fill="both", expand=1)
            Label(frame, text=item, font=label_font, bg="darkgreen", fg="yellow").pack(fill="x")

update_list()
root.bind("<F5>", lambda e: update_list())
root.mainloop()

标签: pythontkinter

解决方案


因此,根据@acw1668 在上面的评论部分建议的解决方案,我将项目的名称传递给函数Button(frame, command=lambda name=item: show_item(name)),然后使用 crated 函数def show_item(name)自动地,我可以用传递的项目的名称做任何我想做的事情。示例代码是:

from tkinter import *
import random

root = Tk()

store_canvas = Frame(root)
store_canvas.pack()

# create the 25 frames
ROWS = COLS = 5
MAX_ITEMS = ROWS * COLS
frames = []
for i in range(MAX_ITEMS):
    frames.append(Frame(store_canvas, width=1520/COLS, height=1030/ROWS, bd=2, relief=SOLID))
    frames[-1].grid(row=i//COLS, column=i%COLS)
    frames[-1].pack_propagate(False)

# function to simulate retrieving data from database table
def retrieve_tiem():
    return [f"Item #{i+1}" for i in range(random.randint(1,MAX_ITEMS))]

# function to show the retrieved items
def update_list():
    Item_list = retrieve_tiem()
    label_font = ("Arial", 20)
    for i, frame in enumerate(frames):
        for w in frame.winfo_children():
            w.destroy()
        if i < len(Item_list):
            item = Item_list[i]
            Button(frame, command=lambda name=item: show_item(name)).pack(fill="both", expand=1)
            Label(frame, text=item, font=label_font, bg="darkgreen", fg="yellow").pack(fill="x")

def show_item(name):
    print(name)


update_list()
root.bind("<F5>", lambda e: update_list())
root.mainloop()

再次感谢@acw1668 的回答。


推荐阅读