Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python tkinter reference in comboboxes created in for loop

My code so far, i want to import images depending on combobox and selection. I need reference to self.box. e.g. self.box1, self.box2 etc or append them somewhere somehow from loop if possible

from Tkinter import *
import ttk


class Application(Frame):
    def __init__(self, master):
        Frame.__init__(self, master, relief="sunken", border=1)
        self.master = master
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        for i in range(9):
            self.box = ttk.Combobox(self, state="readonly")
            self.box["values"] = ("apple", "bannana", "cherry", "raspberry", "blueberry", "lemon", "tomato", "potato",
                                  "None")
            self.box.grid(row=1+i, column=2, pady=1, padx=1, sticky=E+W+N+S)
            self.box.current(i)
            self.box.bind("<<ComboboxSelected>>", self.change_icon)
            print self.box["values"][i]


    def change_icon(self, event):
        self.var_Selected = self.box.current()
        print "The user selected value now is:"
        print self.var_Selected

root = Tk()
root.title("Random title")
root.geometry("500x250")
app = Application(root)
root.mainloop()
like image 370
Stelios Avatar asked May 15 '26 08:05

Stelios


2 Answers

You can have your Application keep a dict object (or a list, but then the implementation is highly index-dependent), store your boxes in the dict with i as the key:

class Application(Frame):
    def __init__(self, master):
        Frame.__init__(self, master, relief="sunken", border=1)
        # Various initialization code here
        self.box_dict = {}

    def create_widgets(self):
        for i in range(9):
            box = ttk.Combobox(self, state="readonly")
            # Do various things with your box object here
            self.box_dict[i] = box
            # Only complication is registering the callback
            box.bind("<<ComboboxSelected>>",
                         lambda event, i=i: self.change_icon(event, i))


    def change_icon(self, event, i):
        self.var_Selected = self.box_dict[i].current()
        print "The user selected value now is:"
        print self.var_Selected

Then access the boxes via self.box_dict[0] etc.

Edit I made updates to the bind and change_icon method to have each box send its index number to change_icon when event is triggered. Edit2 Changed implementation to use dict instead of list, which seems more robust.

like image 169
zehnpaard Avatar answered May 16 '26 23:05

zehnpaard


For those looking for a more explicit solution here's a fully working solution (Python 3.0+)...and remember kids, indexes start at 0.

from tkinter import *
from tkinter import ttk

class Application(Frame):
    def __init__(self, master):
        Frame.__init__(self, master, relief="sunken", border=1)
        self.master = master
        self.grid()

        self.box_dict = {}

        def create_widgets():
            for i in range(9):
                box = ttk.Combobox(self, state="readonly")
                box["values"] = (
                                 "None",
                                 "Apple",
                                 "Bannana",
                                 "Cherry",
                                 "Raspberry",
                                 "Blueberry",
                                 "Lemon",
                                 "Tomato",
                                 "Potato"
                                 )
                box.grid(row=1 + i, column=2, pady=1, padx=1, sticky=E + W + N + S)
                box.current(0)
                self.box_dict[i] = box
                box.bind("<<ComboboxSelected>>",
                         lambda event, i=i: change_icon(event, i))
                print(f"Option {i} is:",box["values"][i])

        def change_icon(event, i):
            var_Selected = self.box_dict[i].current()
            print(f"The user selected of box {i} is:", var_Selected)

        create_widgets()


root = Tk()
root.title("Random title")
root.geometry("500x250")
app = Application(root)
root.mainloop()
like image 42
Mac Avatar answered May 16 '26 21:05

Mac