multiple frames with tkinter - set checkbox default value - python

I want to move my one window tkinter GUI to a step by step with multiple windows. I am trying to set the default value of the checkbox named checkb_ult_tubo to 1 (checked) but although I set the variable to 1, the checkbox is still off by default.
I even tried to decleare a new variable (tk.IntVar) inside the Page5X class block and to set it to 1 but the checkbox still shows off.
This is my code
class Keep(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.shared_data ={
"rvo": tk.StringVar(),
'num_racks': tk.StringVar(),
'num_falcons': tk.StringVar(),
'first_tip': tk.StringVar(),
'ot_2_ip': tk.StringVar(),
'last_tube': tk.StringVar(),
'rack_completo_check' : tk.IntVar()
}
self.frames = {
'StartPage': StartPage(self, self),
'5x': Page5X(self, self),
'40x': Page40X(self, self),
'nfw': PageNFW(self, self),
'pc': PagePC(self, self),
}
self.current_frame = None
self.show_frame('StartPage')
def show_frame(self, name):
if self.current_frame:
self.current_frame.forget()
self.current_frame = self.frames[name]
self.current_frame.pack()
self.current_frame.update_widgets() # <-- update data in widgets
class StartPage(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
label_rvo = tk.Label(self, text='Reactivo a alicuotar:')
label_rvo.pack()
rvo = self.controller.shared_data["rvo"]
rb_rvo1 = tk.Radiobutton(
master=self,
text='Master Mix 5x',
value='5x',
variable=rvo)
rb_rvo1.pack(padx=3, pady=2)
rb_rvo2 = tk.Radiobutton(
master=self,
text='RT Mix 40x',
value='40x',
variable=rvo)
rb_rvo2.pack(padx=3, pady=2)
rb_rvo3 = tk.Radiobutton(
master=self,
text='Nuclease Free Water',
value='nfw',
variable=rvo)
rb_rvo3.pack(padx=3, pady=2)
rb_rvo4 = tk.Radiobutton(
master=self,
text='Positive Control',
value='pc',
variable=rvo)
rb_rvo4.pack(padx=3, pady=2)
button = tk.Button(self, text="Siguiente", command=self.next_page)
button.pack()
def update_widgets(self):
rvo = self.controller.shared_data["rvo"].get()
def next_page(self):
rvo = self.controller.shared_data["rvo"].get()
self.controller.show_frame(rvo)
class Page5X(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
################## SELECCION DEL ULTIMO TUBO ##################
sub_frame2 = tk.Frame(self)
def disable_enable_button():
if boton_ult_tubo["state"] == "normal":
boton_ult_tubo["state"] = "disabled"
else:
boton_ult_tubo["state"] = "normal"
def popup_select_tube():
last_tube = self.controller.shared_data["last_tube"]
def guardar_seleccion_tubo():
entry_ult_tubo.configure(state='normal')
entry_ult_tubo.delete(0, tk.END)
entry_ult_tubo.insert(0, last_tube.get())
entry_ult_tubo.configure(state='readonly')
popup.destroy()
popup = tk.Toplevel(self)
popup.wm_title("Seleccion del ultimo tubo")
label_tips = tk.Label(popup, text='Seleccione el ultimo tubo disponible:')
label_tips.grid(row=1, column=1, columnspan=12, padx=10, pady=10)
for i in range(8):
label_tips = tk.Label(popup, text=str(i + 1))
label_tips.grid(row=2, column=2 + i, padx=10, pady=10)
for j in range(5):
label_tips = tk.Label(popup, text=string.ascii_uppercase[j])
label_tips.grid(row=3 + j, column=1, padx=10, pady=10)
tips_list = []
for i in range(8):
for j in range(5):
tip = tk.Radiobutton(
master=popup,
value=string.ascii_uppercase[j] + str(i + 1),
variable=last_tube)
tips_list.append(tip)
tip.grid(row=3 + j, column=2 + i, padx=10, pady=10)
B1 = ttk.Button(popup, text="Guardar seleccion", command=guardar_seleccion_tubo)
B1.grid(row=11, column=1, columnspan=12, padx=10, pady=10)
popup.resizable(False, False)
popup.mainloop()
checkb_ult_tubo = tk.Checkbutton(sub_frame2,
text="Ultimo rack completo",
variable=self.controller.shared_data['rack_completo_check'],
height=1,
width=15,
command=disable_enable_button,
onvalue=0, offvalue=1)
self.controller.shared_data['rack_completo_check'].set(1)
checkb_ult_tubo.grid(row=1, column=1, columnspan=2, padx=3, pady=3)
label_ult_tubo2 = tk.Label(sub_frame2, text='Ultimo tubo:')
label_ult_tubo2.grid(row=2, column=1, columnspan=2, padx=3, pady=3)
entry_ult_tubo = tk.Entry(sub_frame2, width=4)
entry_ult_tubo.insert(0, 'E8')
entry_ult_tubo.configure(state='readonly')
entry_ult_tubo.grid(row=3, column=1, padx=3, pady=3)
boton_ult_tubo = tk.Button(sub_frame2, text="Seleccionar", state='disable', command=popup_select_tube)
boton_ult_tubo.grid(row=3, column=2, columnspan=1, padx=10, pady=3)
sub_frame2.pack()
def guardar(self):
self.controller.shared_data["num_racks"] = menu_num_racks.get()
self.controller.shared_data["num_falcons"] = menu_num_racks.get()
def update_widgets(self):
rack_completo_check = self.controller.shared_data['rack_completo_check'].get()
class Page40X(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
self.label = tk.Label(self, text="") # <-- create empty label
self.label.pack()
def update_widgets(self):
rvo = self.controller.shared_data["rvo"].get()
self.label["text"] = rvo
class PageNFW(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
self.label = tk.Label(self, text="") # <-- create empty label
self.label.pack()
def update_widgets(self):
rvo = self.controller.shared_data["rvo"].get()
self.label["text"] = rvo
class PagePC(tk.Frame):
def __init__(self, parent, controller):
super().__init__(parent)
self.controller = controller
self.label = tk.Label(self, text="") # <-- create empty label
self.label.pack()
def update_widgets(self):
rvo = self.controller.shared_data["rvo"].get()
self.label["text"] = rvo
if __name__ == "__main__":
keep = Keep()
keep.mainloop()

So I noticed that the onvalue inside of checkb_ult_tubo is 0, and the offvalue is 1. I think that when you set the value of the checkbox to 1, it remained off because the offvalue is 1. Try this:
checkb_ult_tubo = tk.Checkbutton(sub_frame2,
text="Ultimo rack completo",
variable=self.controller.shared_data['rack_completo_check'],
height=1,
width=15,
command=disable_enable_button,
onvalue=1, offvalue=0)

Related

How to give button command from one class to another class Tkinter python?

I am doing one problem now. I want to print something by using "def select" in window 3. I need to give "def select" command to "proceed" button which is present in Window 2. I tried but I don't know how to do that.I am new to programming and developing GUI. So please help me to sort out this error.
class Win1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
Label(self, text= "ISMC", font= ('Helvetica 20 bold')).pack(padx=300, pady=5)
B1=Button(self, text="AUTO", command=lambda:controller.show_frame(Win2)).pack(pady=20, padx=200)
B2=Button(self, text="MANUAL", command=lambda:controller.show_frame(Win3)).pack(pady=20, padx=200)
class Win2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
Label(self, text= "ISMC", font= ('Helvetica 20 bold')).pack(padx=20, pady=40)
Label(self, text= "Configurations", font= ('Helvetica 20 bold')).pack(padx=20, pady=40)
v = StringVar(self, "1")
values = {"BLOCK 1" : "1",
"BLOCK 2" : "2",
"BLOCK 3" : "3"}
for (text, value) in values.items():
Radiobutton(self, text = text, variable = v, bg="light blue", value = value,
indicator = 0, width = 10, command=self.do_auto).pack(pady=20)
B1=Button(self, text="PROCEED", bg="green", fg="white", command=lambda :self.select(str2)).pack(pady=20)
B2=Button(self, text="BACK", bg="red", fg="white", command=lambda:controller.show_frame(Win1)).pack(pady=20)
def do_auto(self):
for var in self.controller.frames[Win3].vars:
var.set(1)
class Win3(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.array = []
for i in range(no_of_relays):
self.array.append("RELAY " + str(i+1))
self.vars = []
val_x=100
val_y=10
for i in range(len(self.array)):
self.vars.append(StringVar())
self.vars[-1].set(0)
c = Checkbutton(self, text=self.array[i], variable=self.vars[-1], onvalue=1, offvalue=0,
command=lambda: self.printSelection(i)).place(x=val_x,y=val_y)
if i<=30:
val_x=val_x+0
val_y=val_y+18
if i>30<=60:
val_x=200
val_y=val_y+18
if i==29:
val_y=10
val_x=200
def printSelection(self, i):
global str1
global str2
global str3
str1=''
str2=''
str3=''
data['id'] = self.array[i]
last=data['id'].rsplit(' ', 1)[-1]
data['Status'] = self.vars[i].get()
str1=str1+last
str3=str3+self.vars[i].get()
selected_id.append(str1)
selected_status.append(str3)
str2="{'id':" + str(selected_id) + ",'Status':" + str(selected_status) + "}"
def select(self,var):
print(var)
selected_status.clear()
selected_id.clear()
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
window = tk.Frame(self)
window.pack(side = "top", fill = "both", expand = True)
self.frames = {}
for F in (Win1, Win2, Win3):
frame = F(window, self)
self.frames[F] = frame
frame.grid(row = 0, column=0, sticky="nsew")
self.show_frame(Win1)
def show_frame(self, window):
frame = self.frames[window]
frame.tkraise()
self.title("Relay Test")
self.geometry('1500x1500')
app = Application()
app.mainloop()
Can anyone please help me

CLASS MATH -- Need Help getting an Int Value from XY -- Super Lost

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()

Python - How to assign OpenMenu choice as a List?

I have created Frame with Entry widget to ask user to input his Username and select a team, that he want to join in and also I have created an OpenMenu Widget with 4 teams that user can join.
I want to know, how to assign list to OpenMenu variations as a list. For example: Selection "Team 1" = team1Members etc.
Also I want to know, how to assign data from Entry Widget to appropriate list. For example, if user have selected "Team 1", his username will append to team1Members list.
from tkinter import *
import tkinter.ttk as ttk
team1Members = []
team2Members = []
team3Members = []
team4Members = []
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 (StartPage, selectionPage, TeamsPage):
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(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
self.startMenu()
def startMenu(self):
heading = Label(self, text="College Tournament Points\n Count Software",
font=('Arial', 25))
heading.grid(row=0, column=0, columnspan=2, padx=240, pady=40)
start_Btn = Button(self, text="Start", font="Arial 16", width=8,
command=lambda: self.controller.show_frame(selectionPage))
start_Btn.grid(row=1, column=0, padx=30, pady=5)
exit_Btn = Button(self, text="EXIT", font="Arial 16", width=8,
command=self.controller.destroy)
exit_Btn.grid(row=1, column=1, padx=30, pady=5)
def starting_Program(self):
pass
class selectionPage(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
self.teamSelect()
def teamSelect(self):
heading = Label(self, text="Become a member of a Team",
font=('Arial', 25))
heading.grid(row=0, column=0, columnspan=2, padx=200, pady=40)
teams = Button(self, text="Teams", font="Arial 24", width=15,
command=lambda: self.controller.show_frame(TeamsPage))
teams.grid(row=1, column=0, padx=270, pady=5)
class TeamsPage(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 Username:", font="Arial 20")
headingTest.grid(row=0, column=0, pady=0)
usernameEnter = Entry(self, width=40)
usernameEnter.grid(row=0, column=1, padx=2, pady=10)
UserName = StringVar(self)
UserName.set("Team1")
AdditionalText = Label(self, text="Please select a team:", font="Arial 18")
AdditionalText.grid(row=1, column=0, sticky=W, pady=15)
teamSelection = OptionMenu(self, UserName, "Team1", "Team2", "Team3", "Team 4") # How to link those variations to team list? For example: Team 1 = team1Members?
teamSelection.grid(row=1, column=1, sticky=W)
confirmBtn = Button(self, text="Submit", font="Arial 16",
command=()) # Command to Save username in teamXMembers list. Depends on the user selection
confirmBtn.config(height=4, width=12)
confirmBtn.grid(row=2, column=2, sticky=E, padx=65, pady=300)
if __name__ == '__main__':
app = CollegeApp()
app.geometry("800x500")
app.title('Points Counter')
app.mainloop()
Screenshot of this window:
There are few ways that could achieve this. The First would be to create a list of teams and unpack them using * in optionMenu then use if else condition to check which list to append to.
Here is a demo
class TeamsPage(ttk.Frame):
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
self.teamList = ["Team1", "Team2", "Team3", "Team 4"]
self.userEntry()
def userEntry(self):
...
self.usernameEnter = Entry(self, width=40)
self.usernameEnter.grid(row=0, column=1, padx=2, pady=10)
self.userName = StringVar(self)
self.userName.set("Team1")
teamSelection = OptionMenu(self, self.userName, *self.teamList)
teamSelection.grid(row=1, column=1, sticky=W)
confirmBtn = Button(self, text="Submit", font="Arial 16",
command= self.updateTeamList) # Command to Save username in teamXMembers list. Depends on the user selection
...
def updateTeamList(self):
if self.userName.get() == self.teamList[0]:
team1Members.append(self.usernameEnter.get())
elif self.userName.get() == self.teamList[1]:
team2Members.append(self.usernameEnter.get())
...
but a better way would be to create a dictionary. something as shown
def __init__(self, parent, controller):
self.controller = controller
ttk.Frame.__init__(self, parent)
self.teamList = {"Team1": team1Members , "Team2": team2Members,
"Team3":team3Members, "Team 4": team4Members}
self.userEntry()
def userEntry(self):
...
self.usernameEnter = Entry(self, width=40)
self.usernameEnter.grid(row=0, column=1, padx=2, pady=10)
self.userName = StringVar(self)
self.userName.set("Team1")
AdditionalText = Label(self, text="Please select a team:", font="Arial 18")
AdditionalText.grid(row=1, column=0, sticky=W, pady=15)
teamSelection = OptionMenu(self, self.userName, *self.teamList.keys())
teamSelection.grid(row=1, column=1, sticky=W)
confirmBtn = Button(self, text="Submit", font="Arial 16",
command= self.updateTeamList) # Command to Save username in teamXMembers list. Depends on the user selection
...
def updateTeamList(self):
self.teamList[self.userName.get()].append(self.usernameEnter.get())

Switching frame automatically in Tkinter

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)

Tkinter change a shared variable

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())

Categories

Resources