Python Forum
Tkinter button in for - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: GUI (https://python-forum.io/forum-10.html)
+--- Thread: Tkinter button in for (/thread-22667.html)



Tkinter button in for - Simpsunt - Nov-21-2019

Hello,

First of all, i'm new here !

Then, I wasn't sure if this post belongs to GUI or general coding issue, kind of both.

I'm creating a GUI and I'm having an issue to create many buttons which are supposed to call a single function with the unique ID of the selected user.

My code :
i = 0
for key, name in self.__model.get_6_users().items():
    print("key_menu = " + str(key) + '-' + name)
    Button(acceuil, text=name + '-' +str(key), command=lambda: self.click_user(key)).\
         grid(column=i, row=2, sticky=N + S + W + E)
    i += 1
Everything is good for the display and with the debugging printing :
Output:
key_menu = 2-Eric key_menu = 5-Batman key_menu = 0-Bob key_menu = 4-PierreAFeu key_menu = 1-Joe key_menu = 3-Emmanuelle
But when I click on any of them, it's always the 3rd ID (Emmanuelle) which is sent to click_user.

I think it's because the Lambda function is compiled only after the for loop (Emmannuelle is the last ID so it's the value taken into account at the end) but I really don't know how to make it work.

I can't make it outside of my for loop because I don't know how many users I'll have to display

Any idea ?

Thanks !


RE: Tkinter button in for - Larz60+ - Nov-22-2019

key is no longer in scope after you exit the for loop,
therefore there's no way to tell what it's value will be when the button is clicked.


RE: Tkinter button in for - Simpsunt - Nov-22-2019

Well that's kind of what I had in mind...

So I changed my code and now it works but it's awful :(

        keys = []
        names = []
        for key, name in self.__model.get_6_users().items():
            keys.append(key)
            names.append(name)
        for i in range(len(keys), 6):
            keys.append('-')
            names.append('-')
        Button(acceuil, text=names[0], command=lambda: self.click_user(keys[0])). \
            grid(column=0, row=2, sticky=N + S + W + E)
        Button(acceuil, text=names[1], command=lambda: self.click_user(keys[1])). \
            grid(column=1, row=2, sticky=N + S + W + E)
        Button(acceuil, text=names[2], command=lambda: self.click_user(keys[2])). \
            grid(column=2, row=2, sticky=N + S + W + E)
        Button(acceuil, text=names[3], command=lambda: self.click_user(keys[3])). \
            grid(column=3, row=2, sticky=N + S + W + E)
        Button(acceuil, text=names[4], command=lambda: self.click_user(keys[4])). \
            grid(column=4, row=2, sticky=N + S + W + E)
        Button(acceuil, text=names[5], command=lambda: self.click_user(keys[5])). \
            grid(column=5, row=2, sticky=N + S + W + E)
        for i in range(0,len(keys)):
            if keys[i] == '-':
                Button(acceuil, text=names[i], state=DISABLED).grid(column=i, row=2, sticky=N + S + W + E)
So I get my keys and names that I put in two != lists and I and values '-' if I don't have enough user to fill the 6 fields.
Then I create my 6 buttons.
Finaly I overwrite the buttons where '-' is set

If you have any better suggestions...?


RE: Tkinter button in for - Larz60+ - Nov-23-2019

post the entire script and I'll take a look.
I need something that I can run