Frankly I don't know what is the problem because first I change how it works - to make it more readable.
But later I released that problem can be because you use external variable k in both Combo. When you set k = 1 to create second Combo then this value 1 will be used in first Combo too. You have to assign value to self.k inside class and use only this self.k inside class. You should send all values explicitly as parameters and you should keep them in class variables.
First I put all data directly in dictionary without using some data[0]or other variable nom
data = {
'Part': ['01_Flat', '02_Curv', '03_RX', '04_RY', '05_RZ', '06_Fsyr', '07_AI'],
'Cutting': ['Manual', 'Laser', 'Gamma', 'Proto']
}
Next I send explicitly key and data to Combo
Combo(root, text='Part', options=data['Part'])
And later I keep all elements inside class using self. - I don't access external data. And when I have Combo assigned to variable then I can get all information directly from Combo - combo_a.key, combo_a.data and I don't have to search it in other objects.
And I use readable variable text instead of k (and I don't need variable i)
class Combo(tk.Frame):
def __init__(self, parent, text, options):
tk.Frame.__init__(self, parent)
self.text = text
self.options = options
self.menubutton = tk.Menubutton(self, text=self.text,
indicatoron=True, borderwidth=1, relief="raised")
self.menu = tk.Menu(self.menubutton, tearoff=False)
self.menubutton.configure(menu=self.menu)
self.menubutton.pack(padx=10, pady=10)
self.choices = {}
for item in self.options:
self.choices[item] = tk.BooleanVar(value=False)
self.menu.add_checkbutton(label=item, variable=self.choices[item],
onvalue=True, offvalue=False, command=self.show)
and I also changed function show() to use self.options and self.choices
def show(self):
values = [self.choices[item].get() for item in self.options]
print(values)
return values
Because this functions gives list of 0,1 (in my version True, False`) which is unreadable so I created function which create list only with selected elements
def get_selected(self):
values = [item for item in self.options if self.choices[item].get() is True ]
return values
And all works without problems.
Full working code:
import tkinter as tk
from tkinter import ttk
# --- classes ---
class Combo(tk.Frame):
def __init__(self, parent, text, options):
tk.Frame.__init__(self, parent)
self.text = text
self.options = options
self.menubutton = tk.Menubutton(self, text=self.text,
indicatoron=True, borderwidth=1, relief="raised")
self.menu = tk.Menu(self.menubutton, tearoff=False)
self.menubutton.configure(menu=self.menu)
self.menubutton.pack(padx=10, pady=10)
self.choices = {}
for item in self.options:
self.choices[item] = tk.BooleanVar(value=False)
self.menu.add_checkbutton(label=item, variable=self.choices[item],
onvalue=True, offvalue=False, command=self.show)
def show(self):
value = [self.choices[item].get() for item in self.options]
print(value, self.get_selected())
return value
def get_selected(self):
value = [item for item in self.options if self.choices[item].get() is True ]
return value
# --- functions ---
def show_all_selections():
results.delete('0.0', 'end')
results.insert('end', f'{combo_a.text}: {combo_a.get_selected()}\n')
results.insert('end', f'{combo_pos.text}: {combo_pos.get_selected()}\n')
# --- main ---
data = {
'Part': ['01_Flat', '02_Curv', '03_RX', '04_RY', '05_RZ', '06_Fsyr', '07_AI'],
'Cutting': ['Manual', 'Laser', 'Gamma', 'Proto']
}
root = tk.Tk()
canva = tk.Canvas(root, width=530, height=200)
canva.pack(fill="both", expand=True)
combo_a = Combo(root, text='Part', options=data['Part'])
a = canva.create_window(125, 50, anchor="nw", window=combo_a)
combo_pos = Combo(root, text='Cutting', options=data['Cutting'])
pos = canva.create_window(225, 50, anchor="nw", window=combo_pos)
results = tk.Text(root, height=4)
results.pack()
button = tk.Button(root, text="Show all selected", command=show_all_selections)
button.pack()
root.mainloop()

(it seems Stackoverflow has problem to display images)
PEP 8 -- Style Guide for Python Code
k, content ofdata[k][i]changes as well. Thereforeshowof the first combobox iterates over other data than the constructor which built theself.choicesdict.nom[k][i]anddata[k][i]? Looks like you haven't included in the codeprint()(andprint(type(...)),print(len(...)), etc.) to see which part of code is executed and what you really have in variables. It is called"print debugging"and it helps to see what code is really doing.self. to keep it inside class - so why do you need class? Why do you setiandkoutside class? It should be hidden inside class. And if you need different values then send it as parameters inCombo(root, i=0, k=1)