Assigning Items From Dictionary's Set To A Combobox
My plan was to create a combobox with the names of individuals, so that user can select a name from the set and enter its points into the Entry box. I tried to do this, but my drop
Solution 1:
ok, so I think I figured it out (I marked changes in the code with comments, they have a lot of "-" so that is how You will know (in total changes in 3 places (5 comments that have a lot of "-"))):
from tkinter import *
from tkinter import messagebox
import tkinter.ttk as ttk
# This code is a simplified version of a full program code. In the original program, there is not only a list
# of individuals, but also lists of team1, team2 ... team4.
# However, now I am only interested in the problems associated with individual list,
# and I cut out all the part of the code related to team.
class CollegeApp(Tk):
def __init__(self):
Tk.__init__(self)
container = ttk.Frame(self)
container.pack(side="top", fill="both", expand=True)
self.frames = {}
for F in (IndividPage, listCheckPage, counterPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(IndividPage)
self.lift()
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
if cont == counterPage: # changes here ----------------------------------------------------------------------------------------------------------
frame.userEntry() # ------------------------------------------------------------------------------
# In this class I have created a window with entry widget to input name of individual and save it in
# eponymous set "Individual"
class IndividPage(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
self.userEntry()
def userEntry(self):
headingTest = Label(self, text="Enter your User Name:", font="Arial 20")
headingTest.grid(row=0, column=0, pady=5, padx=5)
self.usernameEnter = Entry(self, width=40)
self.usernameEnter.grid(row=0, column=1, padx=5, pady=5)
self.TeamName = StringVar(self)
self.TeamName.set("Individual")
confirmBtn = Button(self, text="Confirm User", font="Arial 16",
command=self.confirm)
confirmBtn.config(height=4, width=12)
confirmBtn.grid(row=2, column=2, sticky=E, padx=45, pady=360)
# Checking the "add_to_team" function has been executed and moving to the next page.
def confirm(self):
if self.add_to_team():
self.controller.show_frame(listCheckPage)
# Function to check the presence of input
def add_to_team(self):
user = self.usernameEnter.get()
if len(user) == 0:
messagebox.showwarning(title='No user', message='Please enter a username!')
return
if self.usernameEnter.get():
self.controller.show_frame(listCheckPage)
team_name = self.TeamName.get()
team = teams[team_name]
team.add(user)
self.controller.frames[listCheckPage].team_listboxes[team_name].insert(END, user)
print(teams)
# Class that creates page with lists of four teams and individuals (Focusing on individuals right now)
# Also there is two buttons "Add User" and "Start Counter" to start points calculator
class listCheckPage(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
self.userEntry()
def userEntry(self):
self.team_listboxes = {}
for col_num, teamname in enumerate(teams):
teamMembers = Listbox(self)
teamMembers.config(height=13, width=15)
teamMembers.grid(row=0, column=col_num, padx=5, pady=50, sticky=S)
for i, user in enumerate(teams[teamname]):
teamMembers.insert(i, user)
self.team_listboxes[teamname] = teamMembers
INDHeading = Label(self, text="Individuals", font="Arial 16")
INDHeading.grid(row=0, column=4, pady=0, padx=15, sticky=N)
addUserBtn = Button(self, text="Add User", font="Arial 16",
command=lambda: self.controller.show_frame(IndividPage))
addUserBtn.config(height=3, width=80)
addUserBtn.grid(row=1, column=0, columnspan=5, pady=0, sticky=N)
CounterBtn = Button(self, text="Start Counter", font="Arial 16",
command=lambda: self.controller.show_frame(counterPage))
CounterBtn.config(height=3, width=80)
CounterBtn.grid(row=2, column=0, columnspan=5, pady=0, sticky=N)
# Main problem start here
# This class creating dropdown menu (or combobox) with sets "teamX" and "Individual" but it was unplanned
# I want this combobox to show not all possible sets (team1, team2 etc.).
# Instead of that I want the combobox will show all the names that were entered in the "Individuals" set.
# I would also like to point out that the same process will be used for the sets of team1, team2 etc.
class counterPage(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
# self.userEntry() this method call seems to be useless -------------------------------------------------
def userEntry(self):
indivLabel = Label(self, text="Please select an individual: ", font="Arial 20")
indivLabel.grid(row=0, column=0, pady=10, padx=10)
list_ = [] # changes here ----------------------------------------------------------------------------------------------------
for set_ in teams.values():
for name in set_:
list_.append(name)
IndivName = StringVar(self)
IndivName.set(list_[0] if len(list_) else None)
indivMenu = OptionMenu(self, IndivName, list_)
indivMenu.grid(row=0, column=1, pady=10, padx=10) # --------------------------------------------------------------------------------
backBtn = Button(self, text="BACK", font="Arial 16", height=2, width=6,
command=lambda: self.controller.show_frame(IndividPage))
backBtn.grid(row=7, column=0, sticky=W, pady=245, padx=10)
if __name__ == '__main__':
# teams = {}
# for team in range(1, 5):
# teams[f'Team{team}'] = set()
teams = {'Team1': set(), 'Team2': set(), 'Team3': set(), 'Team4': set(), 'Individual': set()}
pointsInd = []
app = CollegeApp()
# app.geometry("x500")
# app.resizable(False, False)
app.title('Points Counter')
app.mainloop()
Basically I made it so that the userEntry function gets called when user gets to that frame instead when the class is initiated which means it will upadate every time someone switches to that frame, also made it so that it displays each name individually.
Also I suggest following PEP 8 and using snake_case
for function, variable and method names and using CapitalCase
for class names. And I suggest following other PEP 8 rules too (they are not mandatory tho)
Post a Comment for "Assigning Items From Dictionary's Set To A Combobox"