I am aware similar questions have been answered, but I have read them thoroughly and cannot find a solution for myself.
After the BMR_method is done, and either the if, elif, or else options has completed, I want it to automatically load a new class/frame: work . But I cannot figure out how to do this. I tried adding different variations of self.show_frame(work), also tried adding parent/controller parameters to the function but it will either tell me I am missing positional arguments or that the show_frame method doesn't exist. Please help.
import tkinter as tk
from decimal import Decimal
import time
LARGE_FONT = ("Verdana", 12)
def gender():
if var1.get() and var2.get():
print('Please only tick one box')
var1.set(0)
var2.set(0)
elif var1.get():
print('Male')
bmr_male()
elif var2.get():
print('Female')
bmr_female()
else:
print('Please tick male or female')
class theog(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
controller = self
container.pack(side='top', fill='both', expand= True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, BMR, work):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky='nsew')
self.show_frame(StartPage)
def show_frame(self, controller):
frame = self.frames[controller]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Start Page", width = 60)
label.pack()
button = tk.Button(self, text="Begin!",
command=lambda: controller.show_frame(BMR))
button.pack()
class BMR(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="BMR Calculator", width = 20)
label.grid(column=0, row=0, sticky='W')
label_height = tk.Label(self, text="Height (CM)")
label_height.grid(column=3, row=0, sticky='E')
label_weight = tk.Label(self, text="Weight (KG)")
label_weight.grid(column=3, row=1, sticky='E')
label_age = tk.Label(self, text="Age")
label_age.grid(column=3, row=2, sticky='E')
self.text_height = tk.Entry(self, width=20, bg="white")
self.text_height.grid(row=0, column=4, sticky='W')
self.text_weight = tk.Entry(self, width=20, bg="white")
self.text_weight.grid(row=1, column=4, sticky='W')
self.text_age = tk.Entry(self, width=20, bg="white")
self.text_age.grid(row=2, column=4, sticky='W')
self.resultvar = tk.StringVar()
self.result = tk.Label(self, textvariable=self.resultvar)
self.result.grid(row=3, column=1)
self.var1 = tk.StringVar()
self.var1.set(None)
tk.Radiobutton(self, text="Male", bg='white', value='male', variable=self.var1).grid(row=0, column=1, sticky='S')
tk.Radiobutton(self, text="Female", bg='white', value='female', variable=self.var1).grid(row=1, column=1, sticky='S')
tk.Button(self, text="Submit!", width=6, command=self.bmr_method).grid(row=3, column=0, sticky='W')
def bmr_method(self, Entry=None):
if self.text_height.get() and self.text_weight.get() and self.text_age.get() and self.var1.get() == 'male':
bh = float(self.text_height.get()) * 5.0033
bw = float(self.text_weight.get()) * 13.7516
ba = float(self.text_age.get()) * 6.7550
bmr = float(66.4730 + bh + bw - ba)
self.resultvar.set('Your BMR is: ' + str(bmr))
elif self.text_height.get() and self.text_weight.get() and self.text_age.get() and self.var1.get() == 'female':
bh = float(self.text_height.get()) * 1.8496
bw = float(self.text_weight.get()) * 9.5634
ba = float(self.text_age.get()) * 4.6756
bmr = float(655.095 + bh + bw - ba).round(1)
self.resultvar.set('Your BMR is:' + str(bmr) +'\n press continue to find out \n your maintenance calories')
else:
'Please ensure all information has been entered and click again'
self.resultvar.set('Please ensure all \n information has been \n entered and click again')
self.controller.show_frame(work) #I WANT TO OPEN THE CLASS BELOW AFTER THIS METHOD HAS FINISHED
class work(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
controller = self
root = theog()
root.mainloop()
First, your class needs accept and save a reference to the controller so that you can access it later:
class BMR(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
...
Then, you simply need to call the controller method show_frame:
self.controller.switch_frame(work)
Related
Okay, so I am been learning python for 2 weeks and implementing TkInter now, I am trying to make an project where the user can set an Alarm and when the alarm rings the user will hit stop then the program will ask the user some random math questions, I been messing around and got everything up to the Math problem to work, I have a lot of placeholders in place and I am stuck with getting the answer of x and y to return to an INT, I have it made where it will show what x+y will equal and what the user enter but when I run the while loop my program just freezes. I assume its because the answer returns as a Label and that's not an INT, so all my issues are in my Math Class and have been trying for 3 days and cant figure it out. Please anything will be helpful, I tried using the .get method but that also gives me errors.
import tkinter as tk
import time
import datetime
from tkinter import *
from winsound import PlaySound, SND_FILENAME, SND_LOOP, SND_ASYNC
import random
class WakeUpApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side='top', fill='both', expand='true',)
container.grid_rowconfigure(0, minsize=400, weight=1)
container.grid_columnconfigure(0, minsize=250, weight=2)
self.frames = {}
for F in (Alarm, Chooser, Difficulty, Math):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky='nsew')
self.show_frame(Alarm)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
present = datetime.datetime.now()
now = present.strftime("%H:%M:%S")
class Alarm(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
Alarm.hour = tk.StringVar()
Alarm.min = tk.StringVar()
Alarm.sec = tk.StringVar()
hour_a = tk.Entry(self, text=Alarm.hour, width=4).place(x=50, y=50)
min_a = tk.Entry(self, text=Alarm.min, width=4).place(x=70, y=50)
sec_a = tk.Entry(self, text=Alarm.sec, width=4).place(x=90, y=50)
current_time = tk.Label(self, text=f'Current Time: {now}').place(x=0, y=30)
set_time = tk.Label(self, text='Set Time').place(x=0, y=50)
'''
VERY IMPORTANT -- THIS CODE STARTS THE ALARM
setalarm = tk.Button(self, text='Set Alarm', command=lambda: wake())
setalarm.place(x=90, y=90)
'''
setalarm = tk.Button(self, text='Set Alarm', command=lambda: controller.show_frame(Chooser))
setalarm.place(x=90, y=90)
def wake():
alarm_time = f'{Alarm.hour.get()}:{Alarm.min.get()}:{Alarm.sec.get()}'
alarm_clock(alarm_time)
def play_sound(self,):
PlaySound('Sound.wav', SND_FILENAME|SND_LOOP|SND_ASYNC)
def stop_sound(self):
PlaySound(None, SND_FILENAME)
def alarm_clock(alarm_time):
while True:
time.sleep(1)
present = datetime.datetime.now()
now = present.strftime("%H:%M:%S")
print(now)
if now == alarm_time:
break
if now == alarm_time:
play_sound(self)
testbutton = Button(self, text='pls work', command=lambda: stop_sound(self))
testbutton.pack()
class Chooser(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text='Please Choose Your Wake Up Game')
label.pack(pady=50, padx=50)
math = tk.Button(self, text='Math Game',
height=5, width=15,
command=lambda: controller.show_frame(Difficulty))
math.place(x=125, y=75)
guesser = tk.Button(self, text='Guessing Game',
height=5, width=15,
command=lambda: controller.show_frame(Alarm))
guesser.place(x=125, y=175)
class Difficulty(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text='Please Choose Your Difficulty for the Questions')
label.pack(pady=50, padx=50)
level1 = tk.Button(self, text='Level 1 \n ie: 12+17',
height=5, width=15,
command=lambda: controller.show_frame(Math))
level1.place(x=125, y=75)
level2 = tk.Button(self, text='Level 2 \n ie: 12*9',
height=5, width=15,
command=lambda: controller.show_frame(Alarm))
level2.place(x=125, y=175)
level3 = tk.Button(self, text='Level 3 \n ie: 6*7+21',
height=5, width=15,
command=lambda: controller.show_frame(Alarm))
level3.place(x=125, y=275)
class Math(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
x = tk.IntVar()
y = tk.IntVar()
z = tk.IntVar()
ab = tk.IntVar()
x = random.randint(1, 10)
y = random.randint(1, 10)
xy = int(x + y)
problem = tk.Label(self, text=f'{x} + {y}').place(x=0, y=30)
goal = tk.Label(self, text=xy).place(x=0, y=90)
solution = tk.Entry(self, text=z).place(x=0, y=50)
new = tk.Entry(self, text=ab).place(x=0, y=70)
def answer2(self):
py_guess = tk.Label(self, text=ab.get()).place(x=125, y=120)
button2 = tk.Button(self, text='GIVE ME Z PLS', command=lambda: answer())
button2.pack()
button2 = tk.Button(self, text='The Problem', command=lambda: answer2(self))
button2.pack()
def answer():
user_guess = tk.Label(self, text=z.get()).place(x=125, y=100)
level1(user_guess)
def level1(user_guess):
keepGoing = True
while keepGoing:
if (z == xy):
good = tk.Label(self, text='good job').pack()
keepGoing = False
else:
bad = tk.Label(self, text='nope go again').pack()
string_solution = solution.get()
int_solution = int(string_solution)
app = WakeUpApp()
app.mainloop()
I am VERY new to coding/Python, but basically I am trying to move a button and label around using .grid, however, the button and label in the StartPage class just won't move to where I ask (or even at all).
Everything in the BMR class works fine (although the positions you see aren't the final positions, I was just checking).
What is the difference? Why do they not appear at the same position if I give the same details in both classes?
import tkinter as tk
class initials(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side='top', fill='both', expand= True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, BMR):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky='nsew')
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame): #GRID WON'T WORK HOW I WANT IT TO
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Start Page")
label.grid(column=3, row=3, sticky='we')
button = tk.Button(self, text="Calculate BMR",
command=lambda: controller.show_frame(BMR))
button.grid(row=4, column=3, sticky='we')
class BMR(tk.Frame): #GRID WORKS PERFECTLY
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="BMR Calculator")
label.grid(column=1,row=1)
button1 = tk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.grid(column=2, row=2)
submit = tk.Button(self, text="Calculate")
submit.grid(column=3, row=3)
var1 = tk.IntVar()
tk.Checkbutton(self, text='Male', bg='white', variable=var1).grid(column=4, row=4)
var2= tk.IntVar()
tk.Checkbutton(self, text='Female', bg='white', variable=var2).grid(column=5, row=5)
height_inp = tk.Entry(self, width=20, bg="white").grid(column=6, row=6)
app = initials()
app.mainloop()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Start Page", width = 80)
# Added width property in the line above
# and changed sticky property to N
label.grid(row = 3, column=3, sticky = 'N')
label.width = 20
button = tk.Button(self, text="Calculate BMR",
command=lambda: controller.show_frame(BMR))
button.grid(row=4, column=3)
# Removed sticky property for the button
I understand this is how you wish to position the label and the button.
Pleaase see the comments. You can edit the value for the width property and make it suitable for your frame.
I want to create a widget outside his frame, but I don't know what's his master.
this is the structure.
first I created the class of the root. and then 3 classes of frames.
inside the class of the root I put a function. inside the function I created a text widget that should be located in the first one of the 3 frames
I really don't get what I should write as the master of my text widget to locate it in the first frame.
since I am a beginner if you have any advice I'd really appreciate.
thanks for attention here's the code
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import datetime
LARGE_FONT = ("VERDANA", 12)
#user's information manager(classes and method)
class person:
def __init__(self, name, birthday, sex):
self.name = name
self.birthday = birthday
self.sex = sex
def age(self, name, birthday):
user = person(name, birthday, "male")
today = datetime.date.today()
print (today.year - self.birthday.year)
#main windows
class deathCalculatorapp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "age calculator app")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne, PageTwo):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
# all methods here
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
def calculate(self, name, birthday):
user = person(name, birthday, "male")
text_answer = tk.Text(master = , height=3, width=30)
text_answer.grid(column=1, row=9)
answear_text = ("{name} is {age} years old".format(name=name_entry.get(), age=calculate()))
text_answer.insert(tk.END, answear_text)
print (user.age()
#all of the frames
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
#Labels
label = ttk.Label(self, text="deathcalculatorapp", font=LARGE_FONT)
label.grid(column=1, row=0)
first_label = ttk.Label(self, text = "insert your data")
name_label= tk.Label(self, text = "name", bg="lightblue")
year_label = tk.Label(self, text="year", bg ="lightblue", padx=9)
month_label = tk.Label(self, text= "month", bg = "lightblue", padx=3)
day_label = tk.Label(self, text ="day", bg= "lightblue", padx=11)
first_label.grid(column=1, row=3)
name_label.grid(column=0, row=4)
year_label.grid(column=0, row =5)
month_label.grid(column=0, row =6)
day_label.grid(column=0, row = 7)
#Entries
name_entry = tk.Entry(self, text = "", bg = "lightblue")
year_entry = tk.Entry(self,text = "", bg = "lightblue")
month_entry = tk.Entry(self, text = "", bg= "lightblue")
day_entry = tk.Entry(self, text= "", bg = "lightblue")
name_entry.grid(column=1, row=4)
year_entry.grid(column=1,row=5)
month_entry.grid(column=1, row= 6)
day_entry.grid(column=1, row=7)
#Radiobutton about sex
sexdatum = tk.IntVar()
female= ttk.Radiobutton(self, text="female",variable= sexdatum, value="female")
male=ttk.Radiobutton(self, text="male", variable= sexdatum, value="male")
female.grid(column=2, row=4)
male.grid(column=2, row=5)
#Buttons
calculate_button = ttk.Button(self, text="calculate your lifespawn",
command=lambda: controller.age(name_entry.get(),datetime.date(int(year_entry.get()),int(month_entry.get()),int(day_entry.get()))))
calculate_button.grid(column=1, row=8)
button1 = ttk.Button(self, text="Go to Page One",
command=lambda: controller.show_frame("PageOne"))
button2 = ttk.Button(self, text="Go to Page Two",
command=lambda: controller.show_frame("PageTwo"))
button1.grid(column=0, row=0)
button2.grid(column=0, row=1)
#text
#image
image = Image.open(r"/"
r"Users/tommasomasaracchio/Documents/pythonfolder/kushina4.jpg")
image.thumbnail((500,300), Image.ANTIALIAS)
photo = ImageTk.PhotoImage(image)
Photo_label= ttk.Label(self, image=photo)
Photo_label.image = photo
Photo_label.grid(row= 2, column = 1)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = ttk.Label(self, text="This is page 1", font=LARGE_FONT)
label.grid(column=0, row=0)
button = ttk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.grid(column=0, row=0)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = ttk.Label(self, text="This is page 2", font=LARGE_FONT)
label.grid(column=0, row=0)
button = ttk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.grid(column=0, row=0)
if __name__ == "__main__":
app = deathCalculatorapp()
app.mainloop()
It should be master = self.frames['StartPage'].
I have a script that creates a build in TeamCity. I am trying to create a gui that accomplishes this using Tkinder. There are multiple steps to take (ie get credentials -> input buildname -> add template - > etc), so I am using multiple frames to create the steps using the show_frame() command. My problem is the following: I make multiple REST calls, so the first step is getting the user's username and password. However, since all the pages are initialized when the program starts, all my methods that make REST calls error because they don't have the credentials yet.
How can I get the subsequent steps (and their methods) to wait for the user to input username and password?
From the code below, (in the PageOne class) I am trying to get a list of projects from BitBcuket through a REST call so I can dynamically add menu items to a menu, but I can't figure out how to wait to get the username and password.
import json
import requests
import Tkinter as tk
import tkMessageBox
TITLE_FONT = ("Arial", 18, "bold")
class CreateBuild(tk.Tk):
def __init__(self, *args, **kwargs):
self.username = None
self.password = None
self.bit_projects = None
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne, PageTwo):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
def authenticate(self, username, password):
r = requests.head('https://source.amirsys-int.com/projects', auth=(username, password))
if r.status_code == 405:
self.username = username
self.password = password
self.show_frame("PageOne")
else:
tkMessageBox.showinfo("Error", "Incorrect username and/or password.\nPlease enter your Crowd username and "
"password.")
def get_bitbucket_projects(self):
r = requests.get('https://source.amirsys-int.com/rest/api/1.0/projects', auth=(self.username,
self.password))
j = json.loads(r.text)
size = j['size']
repo_dic = {}
for i in range(0, size):
name = j['values'][i]['name']
repo_id = j['values'][i]['key']
repo_dic[name] = repo_id
self.bit_project = repo_dic
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
instructions = tk.Label(self, text="Please enter your Crowd credentials", font=TITLE_FONT)
instructions.grid(column=1, row=1, columnspan=3, padx=30, pady=30)
username = tk.Label(self, text="Crowd Username: ")
username.grid(column=1, row=2, columnspan=2)
password = tk.Label(self, text="Crowd Password: ")
password.grid(column=1, row=3, columnspan=2)
username_entry = tk.Entry(self)
username_entry.grid(column=3, row=2)
password_entry = tk.Entry(self, show="*")
password_entry.grid(column=3, row=3)
button = tk.Button(self, text="Next", command=lambda: controller.authenticate(username_entry.get(),
password_entry.get()))
button.grid(column=4, row=4, padx=10, pady=10)
self.grid_rowconfigure(5, weight=1)
self.grid_columnconfigure(5, weight=1)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
instructions = tk.Label(self, text="Enter build information", font=TITLE_FONT)
instructions.grid(column=1, row=1, columnspan=3, padx=30, pady=30)
build_name = tk.Label(self, text="Build Name: ")
build_name.grid(column=1, row=2, columnspan=2)
build_name_entry = tk.Entry(self)
build_name_entry.grid(column=3, row=2)
project_key = tk.Label(self, text="BitBucket Project: ", anchor="w")
project_key.grid(column=1, row=3, columnspan=2)
project_menu = tk.Menubutton(self, text="Project", anchor="w")
project_menu.grid(column=3, row=3, columnspan=2)
project_menu.menu = tk.Menu(project_menu)
for key, value in controller.bit_projects:
project_menu.menu.add_checkbutton(label=key, variable=value)
self.grid_rowconfigure(4, weight=1)
self.grid_columnconfigure(4, weight=1)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
if __name__ == "__main__":
app = CreateBuild()
app.geometry("800x600")
app.title("Create TeamCity Build")
app.mainloop()
You need to move that code out of the __init__ method (which runs when the program starts) and into the method that gets called when the frame is shown: tkraise().
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
instructions = tk.Label(self, text="Enter build information", font=TITLE_FONT)
instructions.grid(column=1, row=1, columnspan=3, padx=30, pady=30)
build_name = tk.Label(self, text="Build Name: ")
build_name.grid(column=1, row=2, columnspan=2)
build_name_entry = tk.Entry(self)
build_name_entry.grid(column=3, row=2)
project_key = tk.Label(self, text="BitBucket Project: ", anchor="w")
project_key.grid(column=1, row=3, columnspan=2)
self.project_menu = tk.Menubutton(self, text="Project", anchor="w")
self.project_menu.grid(column=3, row=3, columnspan=2)
self.project_menu.menu = tk.Menu(self.project_menu)
self.grid_rowconfigure(4, weight=1)
self.grid_columnconfigure(4, weight=1)
def tkraise(self):
for key, value in self.controller.bit_projects:
self.project_menu.menu.add_checkbutton(label=key, variable=value)
tk.Frame.tkraise(self) # call the superclass to actually raise the frame
I am using a solution found to try and share variables throughout my code, which consists of 'Frame' classes. However, any attempt I make to try and change the value of these shared variables seems to have no effect, and after I attempt to change them, if I print it just returns blank. Any help would be appreciated.
class GolfApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.shared_data = {
"currentcourse": tk.StringVar(),
"numberofteams": tk.IntVar()}
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (MainMenu, CreatePage, ViewPage, GetTeamsPage, ChooseCourse,
AddCourse, LoginSignUp, Login, SignUp, Highscores1, Highscores2,
Scorecards1, Scorecards2):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("LoginSignUp")
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
This is where the solution from the link can be found. I have two variables, 'currentcourse' and 'numberofteams' which I need to share from one frame to others. I am attempting to set these variables in two different classes in the following bits of code.
class GetTeamsPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(background="lightgreen")
def set_teamnumber():
numberofteams = answerentry.get()
numberofteams = self.controller.shared_data["numberofteams"].get()
def testInt(inStr, i, acttyp):
ind = int(i)
if acttyp == '1':
if not inStr[ind].isdigit():
return False
return True
for col in range(7):
self.grid_columnconfigure(col)
for row in range(5):
self.grid_rowconfigure(row)
questionlbl = tk.Label(self,
text="How many teams/players are there?",
bg="lightgreen",
font = "Verdana 20 bold")
questionlbl.grid(column=2,
row=0,
columnspan=3)
answerentry = tk.Entry(self,
text="Enter a number here.",
validate = "key",
textvariable=self.controller.shared_data["numberofteams"])
answerentry.grid(column=2,
row=2,
columnspan=3)
moveonbtn = tk.Button(self,
text="Continue",
height = "3",
width = "40",
bg="darkgreen",
fg="lightgreen",
command = lambda: (controller.show_frame("CreatePage"), set_teamnumber()))
moveonbtn.grid(column=1,
row=5,
columnspan=3)
returnbtn = tk.Button(self,
height="3",
width="40",
bg="darkgreen",
fg="lightgreen",
text="Return to main menu",
command = lambda: controller.show_frame("MainMenu"))
returnbtn.grid(column=4,
row=5,
columnspan=3)
class ChooseCourse(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(background="lightgreen")
cursor.execute("SELECT CourseName FROM Course")
coursetuple = cursor.fetchall()
courselist = [row[0] for row in coursetuple]
def get_choice():
currentcourse = self.controller.shared_data["currentcourse"]
currentcourse = listmenu.get()
for col in range(2):
self.grid_columnconfigure(col, minsize=50)
for row in range(7):
self.grid_rowconfigure(row, minsize=60)
titlelbl = tk.Label(self,
text="Choose a course",
bg="lightgreen",
font = "Verdana 20 bold")
titlelbl.grid(column=2,
row=0)
addbtn = tk.Button(self,
text="Add a new course",
bg="darkgreen",
fg="lightgreen",
command = lambda: controller.show_frame("AddCourse"))
addbtn.grid(column=2,
row=3)
continuebtn = tk.Button(self,
text="Continue",
bg="darkgreen",
fg="lightgreen",
command = lambda: (controller.show_frame("GetTeamsPage"), get_choice))
continuebtn.grid(column=2,
row=4)
returnbtn = tk.Button(self,
text="Return to main menu",
bg="darkgreen",
fg="lightgreen",
command = lambda: controller.show_frame("MainMenu"))
returnbtn.grid(column=2,
row=5)
listmenu = tk.Listbox(self)
for x in range(0, len(courselist)):
listmenu.insert("end", courselist[x])
listmenu.grid(column=2,
row=1)
You start by setting shared_data["current_course"] to an instance of StringVar, but then later you're resetting it to just a string.
Since it is a StringVar, you need to call the set method to set the value:
currentcourse = self.controller.shared_data["currentcourse"]
currentcourse.set(listmenu.get())