tkinter: my second option menu broke the first one

77 Views Asked by At

I made an option menu with tkinter that worked exactly as I wanted to, but when I added a second option menu I started getting error messages and I'm not sure why. I attached the code for the first and second option menu and the error message.

Code for first option menu:

# Option Menu teams

om_team_options = []
for i in team_list:
    om_team_options.append(i.name)
var_team = StringVar(root)
var_team.set(om_team_options[0])

om_team = tk.OptionMenu(frm_create_team, var_team, *om_team_options)
om_team.grid(row=0, column=1)

# - Save team button
btn_team_save = tk.Button(frm_create_team, text='Voeg team toe',   #Line 92
                          command=lambda: add_team())
btn_team_save.grid(row=3, column=5)


def add_team():
    for obj in team_list:
        if var_team.get() == obj.name:
            ingame_list.append(obj)
            place_team(obj.name)
            team_list.remove(obj)
            om_team_options.remove(var_team.get())
    x = om_team['menu'].index(var_team.get())                       #Line 103
    om_team['menu'].delete(x)
    var_team.set(om_team['menu'].entrycget(0, 'label'))


def place_team(name):
    cols, rows = frm_team_list.grid_size()

    lbl = tk.Label(frm_team_list, text=name)
    lbl.grid(row=rows, column=0)

    btn = tk.Button(frm_team_list, text='-', 
                    command=lambda: remove_team(lbl, btn, name))
    btn.grid(row=rows, column=1)


def remove_team(lbl, btn, name):
    for obj in ingame_list:
        if name == obj.name:
            team_list.append(obj)
            add_om_option(name)
            ingame_list.remove(obj)
    lbl.destroy()
    btn.destroy()


def add_om_option(name):
    om_team['menu'].add_command(label=name, command=tk._setit(var_team, name))
    om_team_options.append(name)
    var_team.set(om_team_options[0])

code for second option menu:

# Option menu existing players

om_players_options = ['Player1', 'Player2', 'Player3']
var_players = StringVar(root)
var_players.set(om_players_options[0])

om_team = tk.OptionMenu(frm_create_team, var_players, *om_players_options)
om_team.grid(row=2, column=1)

Error message:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\max\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "C:\Users\max\Desktop\Coding\Python projects\31_Seconds\Test2.py", line 92, in <lambda>
    btn_team_save = tk.Button(frm_create_team, text='Voeg team toe', command=lambda: add_team())
  File "C:\Users\max\Desktop\Coding\Python projects\31_Seconds\Test2.py", line 103, in add_team
    x = om_team['menu'].index(var_team.get())
  File "C:\Users\max\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 3394, in index
    i = self.tk.call(self._w, 'index', index)
_tkinter.TclError: bad menu entry index "Team Blauw"

Process finished with exit code 0

Edit 2: minimal runnable example:

import tkinter as tk
from tkinter import StringVar

root = tk.Tk()
root.geometry('400x600')
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)


# ______________________________________________________________________________________________________________________
# Game Frames

teams = tk.Frame(root, bg='yellow')
teams.grid(sticky='news')


# ______________________________________________________________________________________________________________________
# Teams Frame


# - Team class and instances
class Team:
    def __init__(self, name):
        self.name = str(name)
        self.players = []
        self.current_player = int(0)
        self.points = int(0)


team_blue = Team('Team Blauw')
team_red = Team('Team Rood')
team_green = Team('Team Groen')
team_yellow = Team('Team Geel')


# - Team lists
team_list = [team_blue, team_red, team_green, team_yellow]
ingame_list = []


# - Frames in teams frame
frm_create_team = tk.Frame(teams)
frm_team_list = tk.Frame(teams)

frm_create_team.grid()
frm_team_list.grid()


# - Buttons and lables for team frame
cols, rows = frm_create_team.grid_size()

tk.Label(frm_create_team, text='Choose a team: ').grid(row=0, column=0)
tk.Label(frm_create_team, text='Existing player: ').grid(row=1, column=0)


# - Option Menu teams
om_team_options = []
for i in team_list:
    om_team_options.append(i.name)
var_team = StringVar(root)
var_team.set(om_team_options[0])

om_team = tk.OptionMenu(frm_create_team, var_team, *om_team_options)
om_team.grid(row=0, column=1)

# - Save team button
btn_team_save = tk.Button(frm_create_team, text='Add Team', command=lambda: add_team())
btn_team_save.grid(row=3, column=5)


def add_team():
    for obj in team_list:
        if var_team.get() == obj.name:
            ingame_list.append(obj)
            place_team(obj.name)
            team_list.remove(obj)
            om_team_options.remove(var_team.get())
    x = om_team['menu'].index(var_team.get())
    om_team['menu'].delete(x)
    var_team.set(om_team['menu'].entrycget(0, 'label'))


def place_team(name):
    column, row = frm_team_list.grid_size()
    lbl = tk.Label(frm_team_list, text=name)
    lbl.grid(row=row, column=0)
    btn = tk.Button(frm_team_list, text='-', command=lambda: remove_team(lbl, btn, name))
    btn.grid(row=row, column=1)


def remove_team(lbl, btn, name):
    for obj in ingame_list:
        if name == obj.name:
            team_list.append(obj)
            add_om_option(name)
            ingame_list.remove(obj)
    lbl.destroy()
    btn.destroy()


def add_om_option(name):
    om_team['menu'].add_command(label=name, command=tk._setit(var_team, name))
    om_team_options.append(name)
    var_team.set(om_team_options[0])


# - Option menu existing players
om_players_options = ['Player1', 'Player2', 'Player3']
var_players = StringVar(root)
var_players.set(om_players_options[0])

om_team = tk.OptionMenu(frm_create_team, var_players, *om_players_options)
om_team.grid(row=1, column=1)


root.mainloop()
0

There are 0 best solutions below