Tkinter:创建任意数量的按钮/小部件 [英] Tkinter: creating an arbitrary number of buttons/widgets

查看:25
本文介绍了Tkinter:创建任意数量的按钮/小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我有一个包含如下条目的列表:

So, I've got a list with entries that look like this:

Option1  Placeholder1    2   Placeholder2    0      
Option2  Placeholder1    4              
Option3  Placeholder1    2   Placeholder2    -2   Placeholder3    6

我有一个选项列表框和一个按钮,用于创建一个包含所选选项值的新窗口.我想要做的是在创建这个新窗口时创建 n 个按钮,其中 n 是所选选项的值的数量(即 2、1 和3 分别表示选项 1 到 3).我希望它看起来像这样:

I have a listbox of the Options and a button that creates a new window with the values for the selected Option. What I want to do is to create n number of buttons when this new window is created, where n is the number of values of the selected Options (i.e. 2, 1 and 3 for Options 1 through 3, respectively). I want it to look something like this:

Option1
Placeholder1    [button1 containing value=2]
Placeholder2    [button2 containing value=0]

...当然,如果我只是为我知道将出现的 n 的最大数量分配一个按钮,这当然很简单,但我想知道是否有办法做到这一点更随意.显然,同样的问题也适用于我需要用于值名称('PlaceholderX's)的任意数量的标签.

... which is of course quite simple if I just assign a button for the maximum number of n that I know will be present, but I'm wondering if there's a way to do it more arbitrarily. Obviously the same problem applies to the arbitrary number of Labels I would need to use for the value names (the 'PlaceholderX's) as well.

我一直在尝试阅读有关此类事物、可变变量等的一些资料,而且在大多数情况下(如果不是全部),这似乎是一个非常大的NO-NO".有些人提倡使用 dictionaries,但我真的不明白它应该如何工作(即从 dict 中的条目/值命名变量).

I've been trying to do some reading on this type of thing, variable variables, etc., and it seems it's a very big NO-NO most (if not all) of the time. Some advocate the use of dictionaries, but I don't really get how that's supposed to work (i.e. naming variables from entries/values in a dict).

这是可以(并且应该)完成的事情,还是我最好手动创建所有按钮?

Is this something that can (and should) be done, or am I better off just creating all the buttons manually?

from tkinter import *
import csv

root = Tk()
root.wm_title("RP")

listFrame = Frame(root, bd=5)
listFrame.grid(row=1, column=2)

listbox1 = Listbox(listFrame)
listbox1.insert(1, "Option1")
listbox1.insert(2, "Option2")
listbox1.insert(3, "Option3")
listbox1.pack()

infoFrame = Frame(root, bd=5)
infoFrame.grid(row=1, column=3)

info_message = Message(infoFrame, width=300)
info_message.pack()

# Read stats from file
stat_file = open('DiceTest.csv', 'rU')
all_stats = list(csv.reader(stat_file, delimiter=';'))


def list_selection(event):
    # gets selection and info/stats for info_message
    index = int(listbox1.curselection()[0])
    stats = all_stats[index]

    infotext = str(stats[0])  # just the name
    for n in range(int((len(stats)-2)/2)):  # rest of the stats
        infotext += ('\n' + str(stats[n*2 + 2]) + '\t' + str(stats[n*2 + 3]))

    info_message.config(text=infotext)

listbox1.bind('<ButtonRelease-1>', list_selection)

def load():
    top = Toplevel()
    top.geometry('300x100')

    index = int(listbox1.curselection()[0])
    stats = all_stats[index]

    # some way to create arbitrary buttons/labels here (?)

load_button = Button(root, text='Load', command=load)
load_button.grid(row=2, column=2)

root.mainloop()

哦,每个按钮都应该具有相同的命令/功能,这会将按钮中当前的任何值减少 2.

Oh, and every button should have the same command/function, which reduces whatever value currently is in the button by 2.

推荐答案

想通了!使用字典动态创建小部件工作正常,但在各种按钮按下时调用正确的小部件更加困难.这就是我所拥有的:

Figured it out! Creating the widgets dynamically with a dictionary worked just fine, but calling the correct widget on the various button presses was more difficult. This is what I had:

buttons = dict()
for k in range(len(info)):
    buttons[k] = Button(top, text=info[k], command=lambda: my_function(buttons[k]))

... 这会起作用,但所有按钮按下都会调用该函数,并将最后创建的按钮作为目标.所需要的只是按钮的 command 部分中的一些额外字符:

... which would work, but all button presses would call the function with the last created button as the target. All that was needed was a few extra characters in the command part of the buttons:

buttons = dict()
for k in range(len(info)):
    buttons[k] = Button(top, text=info[k], command=lambda a=k: my_function(buttons[a]))

... 我认为这是可行的,因为它以某种方式将 k 的值存储在 a 中,而不是采用 k 的最后一个已知值,即相当于最后创建的按钮.这是正确的吗?

... which I assume works because it somehow stores the value of k inside a rather than taking the last known value of k, i.e. equivalent to the last created button. Is this correct?

这篇关于Tkinter:创建任意数量的按钮/小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆