Home > Net >  Display the name and surname of a dictionary, after choosing it in a combobox
Display the name and surname of a dictionary, after choosing it in a combobox

Time:07-04

enter image description here

I would like to get the first and last name when I select "trainer" in the combobox named Figure. The name displayed in the first textbox and the last name displayed in the second textbox. Without clicking any buttons, but by selecting only the combobox. The comboboxes and the Tournament and Team dictionaries already work correctly

For example, I select Premier League, then Manchester City, then Trainer, I would like to get "Pep" in the first textbox and "Guardiola" in the second tetxbox, because Guardiola is the Manchester City trainer as written in the dictionary

IMPORTANT: the selection of "Trainer" (in the combobox Figure) must be preceded obligatorily by the selection of the tournament and the team, because Trainer must be that of the dictionary of the selected team

from tkinter import ttk
import tkinter as tk
from tkinter import *

window = tk.Tk()  
window.attributes('-zoomed', True)


#DICTIONARY
Real_Madrid = {"Name": "Real Madrid", "Tournament": "Liga", "Trainer Name": "Carlo", "Trainer Surname": "Ancelotti"}
Manchester_City = {"Name": "Manchester City", "Tournament": "Premier League", "Trainer Name": "Pep", "Trainer Surname": "Guardiola"}


#COMBOBOX ON
tournament=ttk.Combobox(window, width = 18)
tournament.place(x=5, y=15)
tournament['value'] = ["Premier League", "Liga"]
tournament.set("Tournament")

def on_tournament_selected(event):
    selected = tournament.get()
    # get the names for selected gender
    team['value'] = [x['Name'] for x in [Real_Madrid, Manchester_City] if x['Tournament'] == selected]
    team.set('') # clear current selection

tournament.bind('<<ComboboxSelected>>', on_tournament_selected)

team=ttk.Combobox(window, width = 18)
team.place(x=200, y=15)
team.set("Team")

#COMBOBOX DOWN
figure=ttk.Combobox(window, width = 18)
figure.place(x=5, y=100)
figure['value'] = ["Trainer", "Player", "Other"]
figure.set("Figure")

name_figure=ttk.Entry(window, width = 18)
name_figure.place(x=200, y=100)

surname_figure=ttk.Entry(window, width = 18)
surname_figure.place(x=370, y=100)

UPDATE: CODE AFTER SUGGESTIONS

from tkinter import ttk
import tkinter as tk
from tkinter import *

window = tk.Tk()  
window.attributes('-zoomed', True)


#DICTIONARY
teams = {
    "Real Madrid": {
        "Tournament": "Liga",
        "Trainer Name": "Carlo",
        "Trainer Surname": "Ancelotti"
    },
    "Manchester City": {
        "Tournament": "Premier League",
        "Trainer Name": "Pep",
        "Trainer Surname": "Guardiola"
    },
    "Manchester United": {
        "Tournament": "Premier League",
        "Trainer Name": "Erik",
        "Trainer Surname": "Ten Hag"
    }
}



#COMBOBOX ON
tournament=ttk.Combobox(window, width = 18)
tournament.place(x=5, y=15)
tournament['value'] = ["Premier League", "Liga"]
tournament.set("Tournament")

def on_tournament_selected(event):
    req_teams = [] # For all the required teams
    sel_tournament = tournament.get() # Get the tournament
    
    # get the names for selected gender
    for _team in teams.items(): # Go through all the teams in the dictionary
        key = _team[0] # Get the key
        value = _team[1] # Get the value 
        if value['Tournament'] == sel_tournament: # If Tournament of the loop-ed team is our selected tourname, then 
            req_teams.append(key)
    
    team.config(values=req_teams) # Change the values of the combobox

tournament.bind('<<ComboboxSelected>>', on_tournament_selected)

team=ttk.Combobox(window, width = 18)
team.place(x=200, y=15)
team.set("Team")

#COMBOBOX DOWN
figure=ttk.Combobox(window, width = 18)
figure.place(x=5, y=100)
figure['value'] = ["Trainer", "Player", "Other"]
figure.set("Figure")

def on_figure_selected(event):
    # Clear the entry boxes
    name_figure.delete(0,'end') 
    surname_figure.delete(0,'end')
    
    sel = figure.get() # Get the figure
    if sel == 'Trainer':
        if tournament.get() and team.get():

            sel_team = team.get()
            f_name = teams[sel_team]["Trainer Name"]
            l_name = teams[sel_team]["Trainer Surname"]

            # Insert new value onto the entry
            name_figure.insert('end',f_name)
            surname_figure.insert('end',l_name)

name_figure=ttk.Entry(window, width = 18)
name_figure.place(x=200, y=100)

surname_figure=ttk.Entry(window, width = 18)
surname_figure.place(x=370, y=100)

CodePudding user response:

I think this problem can be solved easily if you change the data structure. Right now, you have each team inside each variable, so if you're expanding to more teams, that means you will have to make more variables and search through all of them manually. So instead of that, you can create a main dictionary with team names as the key and the properties(like tournament, trainer) as values. So the structure will look something like:

teams = {
    "Team 1": {
        "Tournament": "Tourn Name",
        "Trainer Name": "Name",
        "Trainer Surname": "Sur Name",
        ...
        ...
    },
    "Team 2": {
        "Tournament": "Tourn Name",
        "Trainer Name": "Name",
        "Trainer Surname": "Sur Name",
        ...
        ...
    },
    ...
    ...
}

So now you have to change your on_tournament_selected to work for the made changes, so:

def on_tournament_selected(event):
    req_teams = [] # For all the required teams
    sel_tournament = tournament.get() # Get the tournament
    
    # get the names for selected gender
    for _team in teams.items(): # Go through all the teams in the dictionary
        key = _team[0] # Get the key
        value = _team[1] # Get the value 
        if value['Tournament'] == sel_tournament: # If Tournament of the loop-ed team is our selected tourname, then 
            req_teams.append(key)
    
    team.config(values=req_teams) # Change the values of the combobox

Now similarly bind the figure comobox to another callback and say:

def on_figure_selected(event):
    # Clear the entry boxes
    name_figure.delete(0,'end') 
    surname_figure.delete(0,'end')
    
    sel = figure.get() # Get the figure
    if sel == 'Trainer':
        if tournament.get() and team.get():

            sel_team = team.get()
            f_name = teams[sel_team]["Trainer Name"]
            l_name = teams[sel_team]["Trainer Surname"]

            # Insert new value onto the entry
            name_figure.insert('end',f_name)
            surname_figure.insert('end',l_name)

I have commented the code to make it more understandable. This type of structure will allow for you to expand and add more teams as you wish without changing the code, hence increasing the modularity of the code.

teams = {
    "Real Madrid": {
        "Tournament": "Liga",
        "Trainer Name": "Carlo",
        "Trainer Surname": "Ancelotti"
    },
    "Manchester City": {
        "Tournament": "Premier League",
        "Trainer Name": "Pep",
        "Trainer Surname": "Guardiola"
    },
    "Manchester United": {
        "Tournament": "Premier League",
        "Trainer Name": "Erik",
        "Trainer Surname": "Ten Hag"
    }
}

It is also notable that the entire on_tournament_selected can be wrapped into a single line of code if you understand List Comprehension, but it will be harder to debug if you get any errors:

def on_tournament_selected(event):
    team.config(values=[_team[0] for _team in teams.items()
                        if _team[1]['Tournament'] == tournament.get()])

# OR
# Remove the function entirely and just change the binding with lambda

tournament.bind('<<ComboboxSelected>>', lambda e: team.config(values=[_team[0] for _team in teams.items()
                                                                      if _team[1]['Tournament'] == tournament.get()])

Bonus Tip: You can also add the binding of the on_figure_selected to the team combobox, so whenever you change the team, the manager name automatically changes instead of having to go and choose a figure again:

team.bind('<<ComboboxSelected>>', on_figure_selected)
  • Related