0

I have a code that generates 12 buttons with names from a list. I'd like to pass those names to a function but currently only last text from button is remembered and it's being used for all buttons. Is there a way (except creating all buttons manually), to have it worked, meaning that proper button name will be passed further?

import tkinter as tk
from tkinter import *

notes_list = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#']
c = 0
r = 0

def notes(note):

    major_scale_steps = [2,2,1,2,2,2,1]
    minor_scale_notes = [2,1,2,2,1,2,2]

    #find where provided note is located and rearrange notes_list accordingly
    ind = notes_list.index(note)
    n_tran = notes_list[ind:]+notes_list[:ind]

    #gather notes using major_scale_steps
    major_scale = [n_tran[0],n_tran[2],n_tran[4],n_tran[5],n_tran[7],n_tran[9], n_tran[11], n_tran[0]]
    minor_scale = [n_tran[0],n_tran[2],n_tran[3],n_tran[5],n_tran[7],n_tran[8], n_tran[10], n_tran[0]]

    return major_scale

def clicked():
    te = notes(i.config('text')[-1])
    #place label with results
    test = tk.Label(window, text=te)
    test.place(x=100, y=150)
    

window = tk.Tk()
window.title('Guitar notes')
window.geometry('320x250')

#create buttons
for i in notes_list:
    i = Button(window, text=i, command=clicked)
    i.config(height=2, width=10)
    i.grid(column=c, row=r)
    c+=1
    if c == 4:
        c=0
        r+=1


window.mainloop()
przystal
  • 3
  • 2
  • place your `test` label out of the func(). `config` it in the function. in your case i think you need to delete/destroy `place_slaves`. you have made all these indexes. it will be always the same result. you need to change it. there are different way, with shuffle, random etc. there are also list methods, with reverse you can play around – bangKok May 26 '21 at 12:29

1 Answers1

0

It is because you used i inside clicked(). When clicked() is executed, i will be the last button created in the main for loop.

You should instead pass the required note to clicked() using functools.partial() and use this note to update the test label.

Also better create the test label outside clicked() and update its text inside the function.

import tkinter as tk
from functools import partial

notes_list = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#']

def notes(note):
    #major_scale_steps = [2,2,1,2,2,2,1]
    #minor_scale_notes = [2,1,2,2,1,2,2]

    #find where provided note is located and rearrange notes_list accordingly
    ind = notes_list.index(note)
    n_tran = notes_list[ind:]+notes_list[:ind]

    #gather notes using major_scale_steps
    major_scale = [n_tran[0],n_tran[2],n_tran[4],n_tran[5],n_tran[7],n_tran[9], n_tran[11], n_tran[0]]
    # shorter version of above:
    #major_scale = [n_tran[x] for x in (0, 2, 4, 5, 7, 9, 11, 0)]
    #minor_scale = [n_tran[0],n_tran[2],n_tran[3],n_tran[5],n_tran[7],n_tran[8], n_tran[10], n_tran[0]]

    return major_scale

def clicked(note):
    # update test label
    test.config(text=notes(note))

window = tk.Tk()
window.title('Guitar notes')
window.geometry('320x250')

# create test label here
test = tk.Label(window)
test.place(x=100, y=150)

#create buttons
for i, note in enumerate(notes_list):
    btn = tk.Button(window, text=note, width=10, height=2, command=partial(clicked, note))
    btn.grid(column=i%4, row=i//4)

window.mainloop()
acw1668
  • 30,224
  • 4
  • 17
  • 30