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()
Related
I have the Win.py file debugged and it worked well. However, according to #Matiiss, I will write the function like
def func():
lbl = ImageLabel(root)
lbl.pack()
lbl.load('D:/Personal/Game/Win.gif')
inside the main file, which is start2.py, but when I inserted the function inside the command, python outputs an error like NameError: name 'root' is not defined. I am not sure whether I need to change root into something else or not because I indeed didn't see root anywhere in either of the file. The following is the codes for the Win.py file.
import tkinter as tk
from PIL import Image, ImageTk
from itertools import count, cycle
class ImageLabel(tk.Label):
def load(self, im):
if isinstance(im, str):
im = Image.open(im)
frames = []
try:
for i in count(1):
frames.append(ImageTk.PhotoImage(im.copy()))
im.seek(i)
except EOFError:
pass
self.frames = cycle(frames)
try:
self.delay = im.info['duration']
except:
self.delay = 100
if len(frames) == 1:
self.config(image=next(self.frames))
else:
self.next_frame()
def unload(self):
self.config(image=None)
self.frames = None
def next_frame(self):
if self.frames:
self.config(image=next(self.frames))
self.after(self.delay, self.next_frame)
I don't know where is the root, but I don't know which argument to be added inside the lbl=ImageLabel().
The codes for start2.py, with correct indent.
import tkinter as tk
import pygame
from playsound import playsound
from Win import ImageLabel
display_width = 1000
display_height = 500
# Set up the display size
white = (255, 255, 255) # White
red = (255, 0, 0) # Red button background
picture = 'D:/Personal/Game UI.jpg' # The location of the picture
pygame.init() # Initialize class+
class Button(object): # Button class
def __init__(self, text, color, x=None, y=None, **kwargs):
self.surface = font.render(text, True, color)
self.WIDTH = self.surface.get_width()
self.HEIGHT = self.surface.get_height()
if 'centered_x' in kwargs and kwargs['centered_x']: # Show the place that a button will show up (x-axis)
self.x = display_width // 2 - self.WIDTH // 2
else:
self.x = x
if 'centered_y' in kwargs and kwargs['centered_y']: # Show the place that a button will show up (y-axis)
self.y = display_height // 2 - self.HEIGHT // 2
else:
self.y = y
def display(self):
screen.blit(self.surface, (self.x, self.y)) # Can't assign a value to a function
def check_click(self, position): # Track mouse behavior to show highlights
x_match = position[0] > self.x and position[0] < self.x + self.WIDTH
y_match = position[1] > self.y and position[1] < self.y + self.HEIGHT
if x_match and y_match:
return True
else:
return False
def start_screen(): # This function is used to load background and music
screen.blit(bg, (0, 0))
game_title = font.render("Start", True, white)
screen.blit(game_title, (display_width // 2 - game_title.get_width() // 2, 150))
play_button = Button("Play", red, None, 350, centered_x=True) # Start the game
exit_button = Button("Exit", white, None, 400, centered_x=True) # Exit the game
play_button.display()
exit_button.display()
pygame.display.update()
while True: # A conditional reading from while loop
if play_button.check_click(pygame.mouse.get_pos()):
play_button = Button('Play', red, None, 350, centered_x=True)
else:
play_button = Button('Play', white, None, 350, centered_x=True)
if exit_button.check_click(pygame.mouse.get_pos()):
exit_button = Button("Exit", red, None, 400, centered_x=True)
else:
exit_button = Button("Exit", red, None, 400, centered_x=True)
play_button.display()
exit_button.display()
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
raise SystemExit
if pygame.mouse.get_pressed()[0]:
if play_button.check_click(pygame.mouse.get_pos()):
break
if exit_button.check_click(pygame.mouse.get_pos()):
break
screen = pygame.display.set_mode((display_width, display_height)) # The use of the functions above
bg = pygame.image.load(picture)
font_addr = pygame.font.get_default_font()
font = pygame.font.Font(font_addr, 36)
start_screen()
LARGE_FONT = ("Verdana", 12) # Font
# TODO: sound is defined here
def fail1():
playsound("D:/Personal/Game/wha-wha.mp3", block=False)
def fail2():
playsound("D:/Personal/Game/Nope-Sound-Effect.wav", block=False) # TODO: bug here, use wav format
def fail3():
playsound("D:/Personal/Game/friday-damn.mp3", block=False)
def fail4():
playsound("D:/Personal/Game/export_4.mp3", block=False)
def fail5():
playsound("D:/Personal/Game/Aww.mp3", block=False)
def fail6():
playsound("D:/Personal/Game/Laughing.mp3", block=False)
def fail7():
playsound("D:/Personal/Game/Incorrect.mp3", block=False)
def give_up():
playsound("D:/Personal/Game/Fail.mp3", block=False)
def try_again():
playsound("D:/Personal/Game/Here-we-go.mp3", block=False)
def success1():
playsound("D:/Personal/Game/Yah.mp3", block=False)
def gif():
top = tk.Toplevel(app)
lbl = ImageLabel(top)
lbl.pack()
lbl.load('D:/Personal/Game/Win.gif')
class SeaofBTCapp(tk.Tk): # Define a class for the tk windows
def __init__(self, *args, **kwargs): # Base properties of tk windows
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 = {}
'''https://stackoverflow.com/questions/64470478/keyerror-class-main-page2-in-python-tkinter For range means
that the buttons will be loaded for multiple times, whenever a new option is added, for range needs to be
defined. '''
for F in (
StartPage, MCQ, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Failure, Success,
Credits): # TODO: add the class number into the for loop here
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): # Start page
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="This will test your chemistry ability. Ready to start?", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button = tk.Button(self, text="Enter",
command=lambda: [controller.show_frame(MCQ), try_again()]) # This will show the next window
button.pack()
button2 = tk.Button(self, text="Cancel",
command=lambda: controller.destroy()) # This will close the window
button2.pack()
class MCQ(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="MCQ test!!! Question 1: What is proton number equal to?", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Atomic mass",
command=lambda: [self.correspondingBehavior("Sorry, you died. Better luck next time!"),
controller.show_frame(Failure), fail1()])
button1.pack()
button2 = tk.Button(self, text="Number of moles",
command=lambda: [self.correspondingBehavior("Sorry, you died. Better luck next time!"),
controller.show_frame(Failure), fail1()])
button2.pack()
button3 = tk.Button(self, text="Atomic number",
command=lambda: controller.show_frame(Q2))
button3.pack()
button4 = tk.Button(self, text="Quit", command=lambda: [controller.show_frame(Credits), give_up()])
button4.pack()
def correspondingBehavior(self, choice):
print(choice)
class Q2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="MCQ test!!! Question 2: Which of the two statements describes the word "
"endothermic?", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Give out heat", command=lambda: [self.correspondingBehavior("Wah-ah-ah-ah..."),
controller.show_frame(Failure), fail2()])
button1.pack()
button2 = tk.Button(self, text="Take in heat", command=lambda: controller.show_frame(Q3))
button2.pack()
button3 = tk.Button(self, text="Give up",
command=lambda: self.correspondingBehavior("Don't give up!"))
button3.pack()
button4 = tk.Button(self, text="Quit", command=lambda: [controller.show_frame(Credits), give_up()])
button4.pack()
def correspondingBehavior(self, choice):
print(choice)
class Q3(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="MCQ test!!! Question :3 he symbol Ag stands for which element?", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Gold",
command=lambda: [self.correspondingBehavior("Wah-ah-ah-ah... EPIC FAIL!!! Gold is Au!"),
controller.show_frame(Failure), fail2()])
button1.pack()
button2 = tk.Button(self, text="Silver", command=lambda: controller.show_frame(Q4))
button2.pack()
button3 = tk.Button(self, text="Hydrogen",
command=lambda: [self.correspondingBehavior("Wah-ah-ah-ah... EPIC FAIL!!! Hydrogen is H!"),
controller.show_frame(Failure), fail2()])
button3.pack()
button4 = tk.Button(self, text="Quit", command=lambda: [controller.show_frame(Credits), give_up()])
button4.pack()
def correspondingBehavior(self, choice):
print(choice)
class Q4(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="MCQ test!!! Question 3: Organic chemistry is the study of the compounds that "
"make up living organisms. All organic molecules contain:", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Carbon only",
command=lambda: [self.correspondingBehavior("WHH! Check your book.."),
controller.show_frame(Failure), fail3()])
button1.pack()
button2 = tk.Button(self, text="Carbon and nitrogen",
command=lambda: [self.correspondingBehavior("Wah-ah-ah-ah... You died!"),
controller.show_frame(Failure), fail3()])
button2.pack()
button3 = tk.Button(self, text="Carbon and hydrogen",
command=lambda: controller.show_frame(Q5))
button3.pack()
button4 = tk.Button(self, text="Quit", command=lambda: [controller.show_frame(Credits), give_up()])
button4.pack()
def correspondingBehavior(self, choice):
print(choice)
class Q5(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="MCQ test!!!A molecule with the formula C3H8 is a(n)", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="hexane",
command=lambda: [self.correspondingBehavior("Nope, it's C6H14"),
controller.show_frame(Failure), fail4()])
button1.pack()
button2 = tk.Button(self, text="propane", command=lambda: controller.show_frame(Q6))
button2.pack()
button3 = tk.Button(self, text="butane",
command=lambda: [self.correspondingBehavior("Nope, it's C4H10"),
controller.show_frame(Failure), fail4()])
button3.pack()
button4 = tk.Button(self, text="Quit", command=lambda: [controller.show_frame(Credits), give_up()])
button4.pack()
def correspondingBehavior(self, choice):
print(choice)
class Q6(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="MCQ test!!!A substance that speeds up the rate of a chemical reaction without "
"undergoing any change itself "
"is known as a _______", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="catalyst",
command=lambda: controller.show_frame(Q7))
button1.pack()
button2 = tk.Button(self, text="cation", command=lambda: [self.correspondingBehavior("Wah-ah-ah-ah... What a "
"pity! But cation is a "
"positive charge."),
controller.show_frame(Failure), fail4()])
button2.pack()
button3 = tk.Button(self, text="counter ion",
command=lambda: [self.correspondingBehavior("Nope, it's the ion that accompanies an ionic "
"species in order to maintain electric "
"neutrality."), controller.show_frame(Failure),
fail4()])
button3.pack()
button4 = tk.Button(self, text="Quit", command=lambda: [controller.show_frame(Credits), give_up()])
button4.pack()
def correspondingBehavior(self, choice):
print(choice)
class Q7(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="MCQ test!!! All of the following are amino acids except:",
font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Tryptophan",
command=lambda: [self.correspondingBehavior("Nope, adenine is a nucleic acid, not an "
"amino acid."), controller.show_frame(Failure),
fail6()])
button1.pack()
button2 = tk.Button(self, text="Tyrosine",
command=lambda: [self.correspondingBehavior("Wah-ah-ah-ah... Adenine is a nucleic acid, "
"not an amino acid."),
controller.show_frame(Failure), fail6()])
button2.pack()
button3 = tk.Button(self, text="Adenine",
command=lambda: controller.show_frame(Q8))
button3.pack()
button4 = tk.Button(self, text="Quit", command=lambda: [controller.show_frame(Credits), give_up()])
button4.pack()
def correspondingBehavior(self, choice):
print(choice)
class Q8(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="MCQ test!!!A mole contains Avogadro's number of items. What is Avogadro's number?",
font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="6023",
command=lambda: [self.correspondingBehavior("Wrong...Check your chemistry book"),
controller.show_frame(Failure), fail5()])
button1.pack()
button2 = tk.Button(self, text="C. 6.02 x 10^-23",
command=lambda: [self.correspondingBehavior("Wah-ah-ah-ah... What a "
"pity! But the value is larger than that..."),
controller.show_frame(Failure), fail5()])
button2.pack()
button3 = tk.Button(self, text="6.023 x 10^23",
command=lambda: controller.show_frame(Q9))
button3.pack()
button4 = tk.Button(self, text="Quit", command=lambda: [controller.show_frame(Credits), give_up()])
button4.pack()
def correspondingBehavior(self, choice):
print(choice)
class Q9(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="MCQ test!!!The person given credit for developing the first modern periodic "
"table is",
font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Democritus",
command=lambda: [self.correspondingBehavior("Wrong...He was famous for the formulation of "
"an atomic theory of the universe"),
controller.show_frame(Failure), fail7()])
button1.pack()
button2 = tk.Button(self, text="Mendeleev",
command=lambda: controller.show_frame(Q10))
button2.pack()
button3 = tk.Button(self, text="Thomson",
command=lambda: [self.correspondingBehavior("Wah-ah-ah-ah... What a "
"pity! He is the one who did a detailed study "
"of cathode rays and proved the existence of "
"the electron in atoms"),
controller.show_frame(Failure), fail7()])
button3.pack()
button4 = tk.Button(self, text="Quit", command=lambda: [controller.show_frame(Credits), give_up()])
button4.pack()
def correspondingBehavior(self, choice):
print(choice)
class Q10(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="MCQ test!!! Does group or period in the periodic table represent outer shell "
"electrons?",
font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Period",
command=lambda: [self.correspondingBehavior("Wrong...You can draw it out and see"),
controller.show_frame(Failure), fail7()])
button1.pack()
button2 = tk.Button(self, text="Group",
command=lambda: (controller.show_frame(Success))) # TODO: find a way
button2.pack()
button3 = tk.Button(self, text="Quit", command=lambda: [controller.show_frame(Credits), give_up()])
button3.pack()
def correspondingBehavior(self, choice):
print(choice)
class Success(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Yay! You have passed my chemistry challenge! Would you like to continue?",
font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Continue", command=[gif(), success1()])
button1.pack()
button2 = tk.Button(self, text="Quit", command=lambda: controller.destroy())
button2.pack()
def correspondingBehavior(self, choice): # Comment
print(choice)
class Failure(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Sorry about that, but you failed. Would you like to try again?",
font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Yes", command=lambda: [controller.show_frame(MCQ), try_again()])
button1.pack()
button2 = tk.Button(self, text="No", command=lambda: controller.show_frame(Credits))
button2.pack()
def correspondingBehavior(self, choice):
print(choice)
app = SeaofBTCapp()
app.mainloop()
'''
Now the codes are in a mess and I am going to write the comments after debugging.
Since there is no information on start2.py, below is an example that you may put in start2.py based on your posted codes:
import tkinter as tk
from Win import ImageLabel
def func():
lbl = ImageLabel(root)
lbl.pack()
lbl.load("D:/Personal/Game/Win.gif")
root = tk.Tk() # the root window for the ImageLabel
func()
root.mainloop()
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)
With the if-statement that I have put in, it would only display the lose statement even if it is correct.
I'm not sure if the way I wrote the statement is correct.
I'm trying to make it that when pressing start both labels would show a number between 1 to 21.
Also, if it's possible, I want to make it that when the hit button is pressed, a number would be added to the label. For example, pressing hit would add 10 + 5, then display the total.
LOCATED IN CLASS TTY:
import tkinter as tk
k = 10
Q = 10
J = 10
A = 11 or 1
class WINDOW(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Memory") #sets the window title
container = tk.Frame(self)#Name of frame to refer to
container.pack(side="top", fill="both", expand=True)#size of window
container.grid_rowconfigure(0, weight=4)#size of window
container.grid_columnconfigure(0, weight=4)
self.frames = {}
for F in (MainMenu, tty):
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("MainMenu")
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
class MainMenu(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(background = 'white')
label = tk.Label(self, text="Memory",font=(15),
borderwidth=5, relief="solid")
label.pack(side="top", fill="y", pady=15, padx=270)
label.pack(fill="both")
button1 = tk.Button(self, text="Start", relief="solid",
borderwidth=5,width=30,
font=(17),command=lambda:
controller.show_frame("tty"))
button1.pack()
button3 = tk.Button(self,
text="Quit",relief="solid",borderwidth=4,width=30,font=(17),command = quit)
button3.place(x="420", y ="50")
button3.pack()
class tty(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(background = "white")
def win():
if score > deal:
tts = tk.Label(self, text="win", font=(20))
tts.pack()
else:
lose = tk.Label(self, text="lose", font=(10))
lose.pack() #The if statement
deal = tk.Label(self, text="18", font=(18))
deal.pack(side="top", fill="y", pady=15, padx=270)
score = tk.Label(self, text="19", font=(18))
score.pack()
f = tk.Frame(self)
button1 = tk.Button(f,borderwidth=5, text="stand", font=(18),command =
lambda: win())#This is the button that i want to display the label
button1.grid(row=0,column=0)
button2 = tk.Button(f, text="Hit",borderwidth=5, font=(18))
button2.grid(row=0,column=1)
f.pack(side="bottom")
button3 = tk.Button(self, text="Quit", font=(18))
button3.pack(side="right", pady=50)
if __name__ == "__main__":
app = WINDOW()
app.geometry("800x400")
app.mainloop()
if score > deal: is comparing two tkinter label objects rather than the value of score and deal. Try getting the value of the labels and converting them to integers before doing the comparision.
if int(score['text']) > int(deal['text']):
To help with your other questions.
To chose a random number between 1 and 21, use the randint function contained inside python's random module (see code below). I've added a new randomise function which will be called after the page is created to randomly select a value for deal and score.
With the hit button, i've added a new function hit which will take the current score, and add another random value to it.
import tkinter as tk
from random import randint
k = 10
Q = 10
J = 10
A = 11 or 1
class WINDOW(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Memory") #sets the window title
container = tk.Frame(self)#Name of frame to refer to
container.pack(side="top", fill="both", expand=True)#size of window
container.grid_rowconfigure(0, weight=4)#size of window
container.grid_columnconfigure(0, weight=4)
self.frames = {}
for F in (MainMenu, tty):
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("MainMenu")
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
class MainMenu(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(background = 'white')
label = tk.Label(self, text="Memory",font=(15),
borderwidth=5, relief="solid")
label.pack(side="top", fill="y", pady=15, padx=270)
label.pack(fill="both")
button1 = tk.Button(self, text="Start", relief="solid",
borderwidth=5,width=30,
font=(17),command=lambda:
controller.show_frame("tty"))
button1.pack()
button3 = tk.Button(self,
text="Quit",relief="solid",borderwidth=4,width=30,font=(17),command = quit)
button3.place(x="420", y ="50")
button3.pack()
class tty(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(background = "white")
self.deal = tk.Label(self, text="18", font=(18))
self.deal.pack(side="top", fill="y", pady=15, padx=270)
self.score = tk.Label(self, text="19", font=(18))
self.score.pack()
f = tk.Frame(self)
button1 = tk.Button(f,borderwidth=5, text="stand", font=(18),command = self.win)#This is the button that i want to display the label
button1.grid(row=0,column=0)
button2 = tk.Button(f, text="Hit",borderwidth=5, font=(18),command = self.hit)
button2.grid(row=0,column=1)
f.pack(side="bottom")
button3 = tk.Button(self, text="Quit", font=(18))
button3.pack(side="right", pady=50)
self.randomise()
def randomise(self):
self.deal['text'] = str(randint(1,21))
self.score['text'] = str(randint(1,21))
def hit(self):
current_score = int(self.score['text'])
new_score = current_score + randint(1,21)
self.score['text'] = str(new_score)
def win(self):
if int(self.score['text']) > int(self.deal['text']):
tts = tk.Label(self, text="win", font=(20))
tts.pack()
else:
lose = tk.Label(self, text="lose", font=(10))
lose.pack() #The if statement
if __name__ == "__main__":
app = WINDOW()
app.geometry("800x400")
app.mainloop()
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'm trying to ask the user to input a number (in this example, they need to enter a number of minutes into the minEntry box). I want to take this number and use it to set multiple variable values by multiplying this value with other numbers. Then i want to take this value and have it displayed in the sublabel box within the __init__ function. Im getting an error message that says 'PageSix' object has no attribute 'peak_rate'. I sort of know what this means but i have no idea how to solve it.
class PageSix(tk.Frame):
def projected_figures(self):
global minEntry
tariff = self.controller.page_get(PageTwo)
minutes=minEntry.get()
self.peak_rate = tk.StringVar()
self.peak_rate.set(0)
self.off_peak = tk.StringVar()
self.off_peak.set(0)
self.line_rental = tk.StringVar()
self.line_rental.set(0)
if tariff.current_tariff == "A":
self.peak_rate.set("Peak Rate: £"+minutes*0.3)
self.off_peak.set("Off-Peak: £"+minutes*0.05)
self.line_rental.set("Line Rental: £15")
elif tariff.current_tariff == "B":
self.peak_rate.set("Peak Rate: £"+minutes*0.1)
self.off_peak.set("Off-Peak: £"+minutes*0.02)
self.line_rental.set("Line Rental: £20")
else:
self.peak_rate.set("Peak Rate: £"+minutes*0.9)
self.off_peak.set("Off-Peak: -")
self.line_rental.set("Line Rental: £30")
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller=controller
label = tk.Label(self, text="Account Balance", font=LARGE_FONT)
label.pack(pady=10,padx=10)
sublabel = tk.Label(self, textvariable=self.peak_rate, font=SMALL_FONT)
sublabel.pack(pady=10,padx=10)
sublabel2 = tk.Label(self, textvariable=self.off_peak, font=SMALL_FONT)
sublabel2.pack(pady=10,padx=10)
sublabel3 = tk.Label(self, textvariable=self.line_rental, font=SMALL_FONT)
sublabel3.pack(pady=10,padx=10)
minLabel = Label(self, text = 'Enter Minutes: ')
minEntry = Entry(self)
minLabel.pack(pady =10, padx = 10, side = TOP, anchor = S)
minEntry.pack(pady =10, padx = 10, side = TOP, anchor = S)
button1 = tk.Button(self, text="View Projected Figures",
command=self.projected_figures)
button1.pack()
button2 = tk.Button(self, text="Back to Menu",
command=lambda: controller.show_frame(StartPage))
button2.pack()
Also the lines tariff = self.controller.get_page(PageTwo) and if self.current_tariff == "x" are referring to this class if it can be of any use.
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller=controller
self.current_tariff = tk.StringVar()
self.current_tariff.set("A")
label = tk.Label(self, text="Current Tariff", font=LARGE_FONT)
label.pack(pady=10,padx=10)
sublabel = tk.Label(self, textvariable=self.current_tariff, font=SMALL_FONT)
sublabel.pack(pady=10,padx=10)
button1 = tk.Button(self, text="Change Tariff",
command=lambda: controller.show_frame(PageSix))
button1.pack()
button2 = tk.Button(self, text="Projected Figures",
command=lambda: controller.show_frame(PageSix))
button2.pack()
button3 = tk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button3.pack()
__init__ gets called as soon as you initialize the class and projected_figures will be called when you call it.
When you try to initialize PageSix, inside of __init__ at sublabel creation line, there is no variable named self.peak_rate since projected_figures hasn't called yet.
Moving variable creations inside of __init__ should solve this issue.
def __init__(self, parent, controller):
...
self.peak_rate = tk.StringVar()
self.peak_rate.set(0)
self.off_peak = tk.StringVar()
self.off_peak.set(0)
self.line_rental = tk.StringVar()
self.line_rental.set(0)
...