Home > Software engineering >  I want to put different command in tkinter Button (made by for())
I want to put different command in tkinter Button (made by for())

Time:11-16

from tkinter import *

window2 = Tk()
Var = ' '
store = ['a',  'b',  'c', 'd']
count = 3

for i in store:
    if i != None:
        chs_store = Button(window2, text = i).grid(row = count  , column = 4)
        count  = 1

I made buttons and placed them on the frame like this. In order to place buttons as same as the order of the list. And now I want to put the different commands into each buttons.

ex) If I click the Button that says 'a', I want Var = 'one', and if I click the Button 'b', I want Var = 'two'.

How should I solve this

CodePudding user response:

Put each command function in a list similar to what you're doing with store

# define the functions you want your buttons to call up here, e.g.:
def func_a():
    print('hello!')

# note: no parentheses () since you're not calling these functions here!
commands = [func_a, func_b, func_c, func_d]
store = ['a', 'b',  'c', 'd']
count = 3

for index, i in enumerate(store):
    if i != None:
        chs_store = Button(window2, text=i, command=commands[index])
        # place your buttons on the grid in a separate line since 'grid' returns
        # None, which means chs_store will have no value anyway
        chs_store.grid(row=count, column=4)
        count  = 1

CodePudding user response:

Just based on the provided code, you can define another list for the position of the selected item in store:

store = ["a", "b", "c", "d"]
position = ["one", "two", "three", "four"]

Then print the corresponding position when a button is clicked.

Below is the modified code:

from tkinter import *

window2 = Tk()

Var = ' '
store = ['a', 'b', 'c', 'd']
position = ['one', 'two', 'three', 'four']

def update_var(pos):
    global Var
    Var = pos
    print(f"{Var=}")

count = 3
for i, pos in zip(store, position):
    Button(window2, text=i, command=lambda pos=pos: update_var(pos)).grid(row=count, column=4)
    count  = 1

window2.mainloop()

CodePudding user response:

If you print out chs_store you will see None, since you have not stored the button object, but the result of the grid method. Therefore, it is better to separate them. In order not to make a counter, I used the enumerate function. I placed the functions that need to be attached to the buttons in a tuple.

from tkinter import *


def fun_a():
    global Var
    Var = 'a'
    print('Var = ', Var)


def fun_b():
    global Var
    Var = 'b'
    print('Var = ', Var)


def fun_c():
    global Var
    Var = 'c'
    print('Var = ', Var)


def fun_d():
    global Var
    Var = 'd'
    print('Var = ', Var)


window2 = Tk()
Var = ' '
funs = (fun_a, fun_b, fun_c, fun_d)
store = ('a', 'b', 'c', 'd')
btns = []

for i, st in enumerate(store):
    b = Button(window2, text=st, command=funs[i])
    b.grid(row=i, column=4)
    btns.append(b)
print(btns)
window2.mainloop()

[<tkinter.Button object .!button>, <tkinter.Button object .!button2>, <tkinter.Button object .!button3>, <tkinter.Button object .!button4>]

Var =  a
Var =  b
Var =  c
Var =  d

If you do not need a separate function for each button, then the code can be shortened. I save the buttons in a list, since the variable b is overwritten at each iteration of the loop.

from tkinter import *
from functools import partial


def fun(s):
    global Var
    Var = s
    print('Var = ', Var)


window2 = Tk()
Var = ' '

store = ('a', 'b', 'c', 'd')
btns = []

for i, st in enumerate(store):
    b = Button(window2, text=st, command=partial(fun, st))
    b.grid(row=i, column=4)
    btns.append(b)

window2.mainloop()
  • Related