Функция в цикле for, которая будет использоваться при нажатии кнопки, не меняется в зависимости от используемой кнопки (Python 3.8.6 Tkinter)

#python #function #loops #for-loop #tkinter

#python #функция #циклы #for-цикл #tkinter

Вопрос:

заранее благодарю вас за любую помощь.

Я пытаюсь создать программу для игры в кости, в которой она берет статистику персонажа из своего класса и использует ее для броска 20-стороннего кубика их модификатор статистики. Я также впервые использую Tkinter. (полный код ниже)

Когда я запускаю этот код сейчас, он генерирует именно то, что я хочу, однако в цикле for функция roll() будет использовать только последнее число из цикла (присваивая ему значение 5 / charisma) для вывода броска кости, независимо от используемой кнопки, где как Я бы хотел, чтобы он использовал значение из используемой кнопки.

Не мог бы кто-нибудь, пожалуйста, пролить свет на то, что я здесь делаю неправильно, поскольку я самоучка и все еще в процессе обучения.

Еще раз спасибо.

 import random
import tkinter as tk

class playerCharacter():
    instances = []
    def __init__(self, name, strength, constitution, dexterity, wisdom, intelligence, charisma):
        self.__class__.instances.append(name)
        self.name = name
        self.strength = strength
        self.constitution = constitution
        self.dexterity = dexterity
        self.wisdom = wisdom
        self.intelligence = intelligence
        self.charisma = charisma

Bekeno = playerCharacter('Bekeno', 0, 1, 2, 3, 4, 5)
Forged = playerCharacter('Forged', 5, 4, 3, 2, 1, 0) #currently unused

character = Bekeno

attributes = {
    "strength": character.strength,
    "constitution": character.constitution,
    "dexterity": character.dexterity,
    "wisdom": character.wisdom,
    "intelligence": character.intelligence,
    "charisma": character.charisma
}

window = tk.Tk() #set up the window of the program
window.title("Dice Roller!")
for i in range(7): #sets the size to be dynamic
    window.columnconfigure(i, weight=1)
    window.rowconfigure(i, weight=1)

for attribute_name, attribute in attributes.items():
    def roll():
        lbl_output['text']= str('D20   '   str(attribute)   ' = '   str(random.randrange(1,21)   attribute))

    frame = tk.Frame( #container for the widgets
        master=window,
        relief=tk.RAISED,
        borderwidth=2
    )
    frame.pack()
 
    label = tk.Label( #Name of the type of check
        master=frame,
        relief=tk.RIDGE,
        text=attribute_name,
        width=10,
        height=4
    )
    label.grid(column=0, row=0)

    button = tk.Button( #Button to roll the check / show modifier
        master=frame,
        command=roll,
        text="Roll "   attribute_name   " : "   str(attribute),
        width=25,
        height=4
    )
    button.grid(column=1, row=0)

frame_end = tk.Frame()#Output at the bottom for dice rolls
frame_end.pack()

lbl_output = tk.Label(
    master=frame_end,
    text='Good luck!',
    height=4
)
lbl_output.pack()

window.mainloop() #runs the program
 

Комментарии:

1. Изменить def roll() на def roll(attribute=attribute) .

2. Большое вам спасибо @acw1668! Мгновенно решил мою проблему, и теперь я понимаю, как это работает. Еще раз спасибо вам за уделенное время!