As I promised yesterday, here comes the real code.
I am about to code a program, for defining the reverberation time in a room. Explaining the whole project, takes too much time. I tried the approach which was suggested, but I do something wrong...
In PageOne, there are all the degrees of absorption of the materials in different sound frequencies and in PageTwo, the user has to enter the area in square meters and choose the material. As soon as the OK-button is pressed the functions getBottomChoice and getWallChoice multiply the values of the materials in PageOne with the userinput, to get the absorption area. But unfortunately it doesn't work. And how can I print out the new values(absorption area) of the chosen materials, just for checkin out? And last but not least, how can I sum up the abs.areas of the chosen materials and print it out, listed by the frequencies ? Thanks in advance!
import tkinter as tk
from tkinter import ttk
from tkinter import *
import math
LARGE_FONT = ("Verdana", 12)
class ReverberationTime(tk.Tk):
def __init__(self,*args,**kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "reverberation time")
tk.Tk.iconbitmap(self,"C:/Users/PC/Desktop/Icons/speaker.ico")
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, PageThree):
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 Pages:
p = 0
z = 1
abs_flä = 1
def __init__(self):
self.parkett_125 = 0.04
self.parkett_250 = 0.04
self.parkett_500 = 0.05
self.parkett_1000 = 0.06
self.parkett_2000 = 0.06
self.parkett_4000 = 0.06
self.linoleum_125 = 0.02
self.linoleum_250 = 0.02
self.linoleum_500 = 0.03
self.linoleum_1000 = 0.03
self.linoleum_2000 = 0.04
self.linoleum_4000 = 0.04
self.pvc_125 = 0.02
self.pvc_250 = 0.02
self.pvc_500 = 0.01
self.pvc_1000 = 0.03
self.pvc_2000 = 0.05
self.pvc_4000 = 0.05
self.tapete_125 = 0.02
self.tapete_250 = 0.03
self.tapete_500 = 0.04
self.tapete_1000 = 0.05
self.tapete_2000 = 0.07
self.tapete_4000 = 0.08
self.glattputz_125 = 0.02
self.glattputz_250 = 0.02
self.glattputz_500 = 0.03
self.glattputz_1000 = 0.03
self.glattputz_2000 = 0.04
self.glattputz_4000 = 0.06
self.mauerziegelwand_125 = 0.02
self.mauerziegelwand_250 = 0.02
self.mauerziegelwand_500 = 0.03
self.mauerziegelwand_1000 = 0.04
self.mauerziegelwand_2000 = 0.05
self.mauerziegelwand_4000 = 0.06
def bottoms(self,parkett_125,parkett_250,parkett_500,parkett_1000,
parkett_2000,parkett_4000,linoleum_125,linoleum_250,linoleum_500,
linoleum_1000,linoleum_2000,linoleum_4000,pvc_125,
pvc_250,pvc_500,pvc_1000,pvc_2000,pvc_4000):
self.parkett_125 = parkett_125
self.parkett_250 = parkett_250
self.parkett_500 = parkett_500
self.parkett_1000 = parkett_1000
self.parkett_2000 = parkett_2000
self.parkett_4000 = parkett_4000
self.linoleum_125 = linoleum_125
self.linoleum_250 = linoleum_250
self.linoleum_500 = linoleum_500
self.linoleum_1000 = linoleum_1000
self.linoleum_2000 = linoleum_2000
self.linoleum_4000 = linoleum_4000
self.pvc_125 = pvc_125
self.pvc_250 = pvc_250
self.pvc_500 = pvc_500
self.pvc_1000 = pvc_1000
self.pvc_2000 = pvc_2000
self.pvc_4000 = pvc_4000
def walls(self,tapete_125,tapete_250,tapete_500,tapete_1000,tapete_2000,tapete_4000,
glattputz_125,glattputz_250,glattputz_500,glattputz_1000,glattputz_2000,glattputz_4000,
mauerziegelwand_125,mauerziegelwand_250,mauerziegelwand_500,mauerziegelwand_1000,mauerziegelwand_2000,mauerziegelwand_4000):
self.tapete_125 = tapete_125
self.tapete_250 = tapete_250
self.tapete_500 = tapete_500
self.tapete_1000 = tapete_1000
self.tapete_2000 = tapete_2000
self.tapete_4000 = tapete_4000
self.glattputz_125 = glattputz_125
self.glattputz_250 = glattputz_250
self.glattputz_500 = glattputz_500
self.glattputz_1000 = glattputz_1000
self.glattputz_2000 = glattputz_2000
self.glattputz_4000 = glattputz_4000
self.mauerziegelwand_125 = mauerziegelwand_125
self.mauerziegelwand_250 = mauerziegelwand_250
self.mauerziegelwand_500 = mauerziegelwand_500
self.mauerziegelwand_1000 = mauerziegelwand_1000
self.mauerziegelwand_2000 = mauerziegelwand_2000
self.mauerziegelwand_4000 = mauerziegelwand_4000
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
label = tk.Label(self, text="reverberation time", font=LARGE_FONT)
label.pack(pady = 10, padx = 10)
button = ttk.Button(self, text="welcome!",
command=lambda: controller.show_frame(PageOne)).pack()
class PageOne(tk.Frame, Pages):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
NORMAL_FONT=("Arial",11)
title = tk.Label(self, text="Please enter the room dimensions.", font=LARGE_FONT)
title.pack(pady = 10, padx = 10)
frame = Frame(self)
frame.pack(pady=20)
self.lenght = StringVar()
self.width = StringVar()
self.height = StringVar()
self.v = StringVar()
dimensions = Frame(frame)
dimensions.pack(side='left', pady=5)
entryfields = Frame(frame)
entryfields.pack(side='right', pady=5)
lblLenght = Label(dimensions, text="lenght:", font=NORMAL_FONT)
lblLenght.pack(pady=3)
lblWidth = Label(dimensions, text="width:", font=NORMAL_FONT)
lblWidth.pack(pady=4)
lblHeight = Label(dimensions, text="height:", font=NORMAL_FONT)
lblHeight.pack(pady=4)
lblVolume = Label(dimensions, textvariable = self.v)
lblVolume.pack()
entLength = Entry(entryfields, textvariable = self.lenght)
entLength.pack(pady=6)
entWidth = Entry(entryfields, textvariable = self.width)
entWidth.pack(pady=6)
entHeight = Entry(entryfields, textvariable = self.height)
entHeight.pack(pady=6)
btncalculate = ttk.Button(self, text="calculate")
btncalculate.pack()
btncalculate.bind("<Button-1>", self.calculate)
btnPageTwo = ttk.Button(self, text="Page 2", command=lambda: controller.show_frame(PageTwo))
btnPageTwo.pack()
btnStartPage = ttk.Button(self, text="Start Page", command=lambda: controller.show_frame(StartPage))
btnStartPage.pack()
def calculate(self, carryout):
try:
l = float(self.lenght.get())
b = float(self.width.get())
h = float(self.height.get())
m = l*b*h
self.v.set("volume: % .2f m³" % m)
Pages.p = m
except ValueError:
tk.messagebox.showinfo('No valid input.','Please enter only numbers!',icon = 'warning')
class PageTwo(tk.Frame, Pages):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
NORMAL_FONT=("Arial",11)
title = tk.Label(self, text="Please select the bottom abilities.", font=LARGE_FONT)
title.pack(pady = 10, padx = 10)
self.bottomMaterial =StringVar()
self.bottom = StringVar()
self.wallMaterial =StringVar()
self.wall = StringVar()
frame = Frame(self)
frame.pack(pady=20)
dimensions = Frame(frame)
dimensions.pack(side='left', pady=5)
entBottom = Entry(dimensions, textvariable = self.bottom)
entBottom.grid(pady = 5)
self.cboBottomMaterial = ttk.Combobox(dimensions, textvariable = self.bottomMaterial, state = 'readonly',font = ('arial', 14, 'bold'), width = 19)
self.cboBottomMaterial ['value'] = ('Parkett', 'Linoleum', 'PVC')
self.cboBottomMaterial.current(0)
self.cboBottomMaterial.grid()
btnBottomChoice = ttk.Button(dimensions, text = "OK", command = self.getBottomChoice)
btnBottomChoice.grid()
entWall = Entry(dimensions, textvariable = self.wall)
entWall.grid(pady = 5)
self.cboWallMaterial = ttk.Combobox(dimensions, textvariable = self.wallMaterial, state = 'readonly',font = ('arial', 14, 'bold'), width = 19)
self.cboWallMaterial ['value'] = ('Tapete', 'Glattputz', 'Mauerziegelwand')
self.cboWallMaterial.current(0)
self.cboWallMaterial.grid()
btnWallChoice = ttk.Button(dimensions, text = "OK", command = self.getWallChoice)
btnWallChoice.grid()
btnsumAbsorptionArea = ttk.Button(self, text="sum")
btnsumAbsorptionArea.pack()
btnsumAbsorptionArea.bind("<Button-1>", self.sumAbsorptionArea)
btnPageTwo = ttk.Button(self, text="Page 1", command=lambda: controller.show_frame(PageOne))
btnPageTwo.pack()
btnStartPage = ttk.Button(self, text="Start Page", command=lambda: controller.show_frame(StartPage))
btnStartPage.pack()
btnStartPage = ttk.Button(self, text="Page 3", command=lambda: controller.show_frame(PageThree))
btnStartPage.pack()
def getBottomChoice(self):
if self.cboBottomMaterial.get() == "Parkett":
self.bottoms(
self.parkett_125 * float(self.bottom.get()),
self.parkett_250 * float(self.bottom.get()),
self.parkett_500 * float(self.bottom.get()),
self.parkett_1000 * float(self.bottom.get()),
self.parkett_2000 * float(self.bottom.get()),
self.parkett_4000 * float(self.bottom.get())
)
elif self.cboBottomMaterial.get() == "Linoleum":
self.bottoms(
self.linoleum_125 * float(self.bottom.get()),
self.linoleum_250 * float(self.bottom.get()),
self.linoleum_500 * float(self.bottom.get()),
self.linoleum_1000 * float(self.bottom.get()),
self.linoleum_2000 * float(self.bottom.get()),
self.linoleum_4000 * float(self.bottom.get())
)
elif self.cboBottomMaterial.get() == "PVC":
self.bottoms(
self.pvc_250 * float(self.bottom.get()),
self.pvc_500 * float(self.bottom.get()),
self.pvc_1000 * float(self.bottom.get()),
self.pvc_2000 * float(self.bottom.get()),
self.pvc_4000 * float(self.bottom.get())
)
elif self.cboBottomMaterial.get() == "":
messagebox.showinfo('No valid input.','Please select.',icon = 'warning')
def getWallChoice(self):
if self.cboWallMaterial.get() == "Tapete":
self.walls(
self.tapete_125 * float(self.wall.get()),
self.tapete_250 * float(self.wall.get()),
self.tapete_500 * float(self.wall.get()),
self.tapete_1000 * float(self.wall.get()),
self.tapete_2000 * float(self.wall.get()),
self.tapete_4000 * float(self.wall.get())
)
elif self.cboWallMaterial.get() == "Glattputz":
self.walls(
self.glattputz_125 * float(self.wall.get()),
self.glattputz_250 * float(self.wall.get()),
self.glattputz_500 * float(self.wall.get()),
self.glattputz_1000 * float(self.wall.get()),
self.glattputz_2000 * float(self.wall.get()),
self.glattputz_4000 * float(self.wall.get())
)
elif self.cboWallMaterial.get() == "Mauerziegelwand":
self.walls(
self.mauerziegelwand_250 * float(self.wall.get()),
self.mauerziegelwand_500 * float(self.wall.get()),
self.mauerziegelwand_1000 * float(self.wall.get()),
self.mauerziegelwand_2000 * float(self.wall.get()),
self.mauerziegelwand_4000 * float(self.wall.get())
)
elif self.cboWallMaterial.get() == "":
messagebox.showinfo('No valid input.','Please select.',icon = 'warning')
def sumAbsorptionArea(self,sum):
sum = self.getBottomChoice + self.getWallChoice
print (sum)
class PageThree(tk.Frame, Pages):
def passvariable(self, var):
self.s.set("volume: % .2f m³" % Pages.p)
def absorptionsrate(self, var):
self.abs_rate.set("volume: % .2f m³" % Pages.abs_flä)
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
frame = Frame(self)
frame.pack(pady=20)
result_var = StringVar()
selected_var = StringVar()
self.s = StringVar()
items_for_listbox = ["Musik","Sprache","Vortrag","Spr.+Vor.","Sport"]
self.abs_rate = StringVar()
def select(event):
a = mylistbox.get(ANCHOR)
Pages.z = curselection(a)
selected_var.set(Pages.z)
def curselection(a):
if a=="Musik":
T_soll_A1 = 0.45*math.log10(Pages.p)+0.07
return (T_soll_A1)
elif a=="Sprache":
T_soll_A2 = 0.37*math.log10(Pages.p)-0.14
return (T_soll_A2)
elif a=="Vortrag":
T_soll_A3 = 0.32*math.log10(Pages.p)-0.17
return (T_soll_A3)
elif a=="Spr.+Vor.":
T_soll_A4 = 0.26*math.log10(Pages.p)-0.14
return (T_soll_A4)
elif a=="Sport":
T_soll_A5 = 0.75*math.log10(Pages.p)-1
return (T_soll_A5)
def calc():
if mylistbox.get(ACTIVE):
Abs_Fl_ges = 0.163 * Pages.p / Pages.z
Absorber = Abs_Fl_ges - Pages.abs_flä
result_var.set(Absorber)
elif Pages.z == 0:
messagebox.showinfo("No selection")
self.dimension = Frame(frame)
self.dimension.pack(side='left', pady=5)
lblPageTwo = tk.Label(self, text="Page 2", font=LARGE_FONT)
lblPageTwo.pack(pady = 10, padx = 10)
lblAbs_rate = tk.Label(self.dimension, textvariable = self.abs_rate)
lblAbs_rate.pack()
pasvar = tk.Label(self.dimension, textvariable = self.s)
pasvar.pack()
lblselection = tk.Label(self.dimension, textvariable=selected_var)
lblselection.pack(expand=YES)
selected_var.set("No selection")
lblresult = Label(self.dimension, textvariable=result_var)
lblresult.pack(expand=YES)
result_var.set("No result")
listbox_frame = Frame(self.dimension)
listbox_frame.pack(expand=YES)
mylistbox = Listbox(listbox_frame, height=5, width=10, font=('times',18))
mylistbox.bind('<<ListboxSelect>>', select)
mylistbox.grid(row=0, column=0)
mylistbox.insert(END, *items_for_listbox)
scroll = Scrollbar(listbox_frame, orient=VERTICAL) # the alignment of the scrollbar
mylistbox["yscrollcommand"] = scroll.set # link the list with the scroll
scroll["command"] = mylistbox.yview # link the scroll with the scroll
scroll.grid(row=0, column=1, sticky=N+S) #sticky=N+S+E)
btnAbsorber=Button(self.dimension, text="Fläche der Absorber", command=calc)
btnAbsorber.pack(expand=YES)
btnStartPage = ttk.Button(self, text="Start Page", command=lambda: controller.show_frame(StartPage))
btnStartPage.pack()
btnPageOne = ttk.Button(self, text="Page 1", command=lambda: controller.show_frame(PageOne))
btnPageOne.pack()
btnPageTwo = ttk.Button(self, text="Page 2", command=lambda: controller.show_frame(PageTwo))
btnPageTwo.pack()
btnPassVariable = ttk.Button(self, text="pasvariable")
btnPassVariable.pack()
btnPassVariable.bind("<Button-1>", self.passvariable)
btnAbs_rate = ttk.Button(self, text="pass absorption rate")
btnAbs_rate.pack()
btnAbs_rate.bind("<Button-1>", self.absorptionsrate)
app = ReverberationTime()
app.mainloop() ```
Ok so going off of our conversation in the comments and some assumptions I had to make about how things connect I have refactored your code.
Let me know if anything is not working as exspected.
4 spaces for indention is the standard. It helps with readability and if you follow the standard you can avoid issues like mismatching indention.
Make sure you have all your imports in your examples as this is an important troubleshooting step and lets us know what libraries we may need to test your examples.
I have refactored your code to follow the PEP8 standard. You had a mix of formatting going on and nothing was consistent.
It can be tricky to inherit from multiple classes so instead inherit from Frame and then create a class attribute that is an instance of Pages
Your functions that create new values from the attributes in Pages doesn't work like you are expecting. Instead you will want to sum everything then return that summed value.
Your math in your sumAbsorptionArea method cannot work as you are using a reference to methods instead of executing those methods.
You use a mix of command and bind on your buttons for some reason and because of this you have to have an event variable in some of your functions/methods. Instead just use command.
Personally you use a lot of lines up for defining attributes. I would work out a way to shorten this. Preferable a list of values or a dictionary would work well here. You can work that one out on your own though. :D
Refactored code:
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import math
LARGE_FONT = ("Verdana", 12)
class ReverberationTime(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "reverberation time")
# tk.Tk.iconbitmap(self, "C:/Users/PC/Desktop/Icons/speaker.ico")
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, PageThree):
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 Pages:
p, z, abs_flä = 0, 1, 1
def __init__(self):
self.parkett_125 = 0.04
self.parkett_250 = 0.04
self.parkett_500 = 0.05
self.parkett_1000 = 0.06
self.parkett_2000 = 0.06
self.parkett_4000 = 0.06
self.linoleum_125 = 0.02
self.linoleum_250 = 0.02
self.linoleum_500 = 0.03
self.linoleum_1000 = 0.03
self.linoleum_2000 = 0.04
self.linoleum_4000 = 0.04
self.pvc_125 = 0.02
self.pvc_250 = 0.02
self.pvc_500 = 0.01
self.pvc_1000 = 0.03
self.pvc_2000 = 0.05
self.pvc_4000 = 0.05
self.tapete_125 = 0.02
self.tapete_250 = 0.03
self.tapete_500 = 0.04
self.tapete_1000 = 0.05
self.tapete_2000 = 0.07
self.tapete_4000 = 0.08
self.glattputz_125 = 0.02
self.glattputz_250 = 0.02
self.glattputz_500 = 0.03
self.glattputz_1000 = 0.03
self.glattputz_2000 = 0.04
self.glattputz_4000 = 0.06
self.mauerziegelwand_125 = 0.02
self.mauerziegelwand_250 = 0.02
self.mauerziegelwand_500 = 0.03
self.mauerziegelwand_1000 = 0.04
self.mauerziegelwand_2000 = 0.05
self.mauerziegelwand_4000 = 0.06
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="reverberation time", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button = ttk.Button(self, text="welcome!",
command=lambda: controller.show_frame(PageOne)).pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
super(PageOne).__init__()
self.Pages = Pages()
normal_font = ("Arial", 11)
tk.Label(self, text="Please enter the room dimensions.", font=LARGE_FONT).pack(pady=10, padx=10)
frame = tk.Frame(self)
frame.pack(pady=20)
self.length = tk.StringVar()
self.width = tk.StringVar()
self.height = tk.StringVar()
self.v = tk.StringVar()
dimensions = tk.Frame(frame)
dimensions.pack(side='left', pady=5)
entry_fields = tk.Frame(frame)
entry_fields.pack(side='right', pady=5)
tk.Label(dimensions, text="length:", font=normal_font).pack(pady=3)
tk.Label(dimensions, text="width:", font=normal_font).pack(pady=4)
tk.Label(dimensions, text="height:", font=normal_font).pack(pady=4)
tk.Label(dimensions, textvariable=self.v).pack()
tk.Entry(entry_fields, textvariable=self.length).pack(pady=6)
tk.Entry(entry_fields, textvariable=self.width).pack(pady=6)
tk.Entry(entry_fields, textvariable=self.height).pack(pady=6)
ttk.Button(self, text="calculate", command=self.calculate).pack()
ttk.Button(self, text="Page 2", command=lambda: controller.show_frame(PageTwo)).pack()
ttk.Button(self, text="Start Page", command=lambda: controller.show_frame(StartPage)).pack()
def calculate(self):
try:
l = float(self.length.get())
b = float(self.width.get())
h = float(self.height.get())
m = l*b*h
self.v.set("volume: % .2f m³" % m)
self.Pages.p = m
except ValueError:
tk.messagebox.showinfo('No valid input.', 'Please enter only numbers!', icon = 'warning')
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# normal_font = ("Arial", 11) # not used
self.Pages = Pages()
title = tk.Label(self, text="Please select the bottom abilities.", font=LARGE_FONT)
title.pack(pady=10, padx=10)
self.bottomMaterial = tk.StringVar()
self.bottom = tk.StringVar()
self.wallMaterial = tk.StringVar()
self.wall = tk.StringVar()
frame = tk.Frame(self)
frame.pack(pady=20)
dimensions = tk.Frame(frame)
dimensions.pack(side='left', pady=5)
tk.Entry(dimensions, textvariable=self.bottom).grid(pady=5)
self.cboBottomMaterial = ttk.Combobox(dimensions, textvariable=self.bottomMaterial,
state='readonly', font=('arial', 14, 'bold'), width=19)
self.cboBottomMaterial['value'] = ('Parkett', 'Linoleum', 'PVC')
self.cboBottomMaterial.current(0)
self.cboBottomMaterial.grid()
ttk.Button(dimensions, text="OK", command=self.get_bottom_choice).grid()
tk.Entry(dimensions, textvariable=self.wall).grid(pady=5)
self.cboWallMaterial = ttk.Combobox(dimensions, textvariable=self.wallMaterial,
state='readonly', font=('arial', 14, 'bold'), width=19)
self.cboWallMaterial['value'] = ('Tapete', 'Glattputz', 'Mauerziegelwand')
self.cboWallMaterial.current(0)
self.cboWallMaterial.grid()
ttk.Button(dimensions, text="OK", command=self.get_wall_choice).grid()
ttk.Button(self, text="sum", command=self.sum_absorption_area).pack()
ttk.Button(self, text="Page 1", command=lambda: controller.show_frame(PageOne)).pack()
ttk.Button(self, text="Start Page", command=lambda: controller.show_frame(StartPage)).pack()
ttk.Button(self, text="Page 3", command=lambda: controller.show_frame(PageThree)).pack()
def get_bottom_choice(self):
if self.cboBottomMaterial.get() == "Parkett":
parkett_125 = self.Pages.parkett_125 * float(self.bottom.get())
parkett_250 = self.Pages.parkett_250 * float(self.bottom.get())
parkett_500 = self.Pages.parkett_500 * float(self.bottom.get())
parkett_1000 = self.Pages.parkett_1000 * float(self.bottom.get())
parkett_2000 = self.Pages.parkett_2000 * float(self.bottom.get())
parkett_4000 = self.Pages.parkett_4000 * float(self.bottom.get())
return sum([parkett_125, parkett_250, parkett_500, parkett_1000, parkett_2000, parkett_4000])
elif self.cboBottomMaterial.get() == "Linoleum":
linoleum_125 = self.Pages.linoleum_125 * float(self.bottom.get()),
linoleum_250 = self.Pages.linoleum_250 * float(self.bottom.get())
linoleum_500 = self.Pages.linoleum_500 * float(self.bottom.get())
linoleum_1000 = self.Pages.linoleum_1000 * float(self.bottom.get())
linoleum_2000 = self.Pages.linoleum_2000 * float(self.bottom.get())
linoleum_4000 = self.Pages.linoleum_4000 * float(self.bottom.get())
return sum([linoleum_125, linoleum_250, linoleum_500, linoleum_1000, linoleum_2000, linoleum_4000])
elif self.cboBottomMaterial.get() == "PVC":
pvc_250 = self.Pages.pvc_250 * float(self.bottom.get()),
pvc_500 = self.Pages.pvc_500 * float(self.bottom.get())
pvc_1000 = self.Pages.pvc_1000 * float(self.bottom.get())
pvc_2000 = self.Pages.pvc_2000 * float(self.bottom.get())
pvc_4000 = self.Pages.pvc_4000 * float(self.bottom.get())
return sum([pvc_250, pvc_500, pvc_1000, pvc_2000, pvc_4000])
elif self.cboBottomMaterial.get() == "":
messagebox.showinfo('No valid input.', 'Please select.', icon='warning')
return 0
def get_wall_choice(self):
if self.cboWallMaterial.get() == "Tapete":
tapete_125 = self.Pages.tapete_125 * float(self.wall.get())
tapete_250 = self.Pages.tapete_250 * float(self.wall.get())
tapete_500 = self.Pages.tapete_500 * float(self.wall.get())
tapete_1000 = self.Pages.tapete_1000 * float(self.wall.get())
tapete_2000 = self.Pages.tapete_2000 * float(self.wall.get())
tapete_4000 = self.Pages.tapete_4000 * float(self.wall.get())
return sum([tapete_125, tapete_250, tapete_500, tapete_1000, tapete_2000, tapete_4000])
elif self.cboWallMaterial.get() == "Glattputz":
glattputz_125 = self.Pages.glattputz_125 * float(self.wall.get())
glattputz_250 = self.Pages.glattputz_250 * float(self.wall.get())
glattputz_500 = self.Pages.glattputz_500 * float(self.wall.get())
glattputz_1000 = self.Pages.glattputz_1000 * float(self.wall.get())
glattputz_2000 = self.Pages.glattputz_2000 * float(self.wall.get())
glattputz_4000 = self.Pages.glattputz_4000 * float(self.wall.get())
return sum([glattputz_125, glattputz_250, glattputz_500, glattputz_1000, glattputz_2000, glattputz_4000])
elif self.cboWallMaterial.get() == "Mauerziegelwand":
mauerziegelwand_250 = self.Pages.mauerziegelwand_250 * float(self.wall.get())
mauerziegelwand_500 = self.Pages.mauerziegelwand_500 * float(self.wall.get())
mauerziegelwand_1000 = self.Pages.mauerziegelwand_1000 * float(self.wall.get())
mauerziegelwand_2000 = self.Pages.mauerziegelwand_2000 * float(self.wall.get())
mauerziegelwand_4000 = self.Pages.mauerziegelwand_4000 * float(self.wall.get())
return sum([mauerziegelwand_250, mauerziegelwand_500, mauerziegelwand_1000,
mauerziegelwand_2000, mauerziegelwand_4000])
elif self.cboWallMaterial.get() == "":
messagebox.showinfo('No valid input.', 'Please select.', icon='warning')
return 0
def sum_absorption_area(self):
the_sum = self.get_bottom_choice() + self.get_wall_choice()
print(the_sum)
class PageThree(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.Pages = Pages()
self.s = tk.StringVar()
self.result_var = tk.StringVar()
self.selected_var = tk.StringVar()
self.selected_var.set("No selection")
self.result_var.set("No result")
self.abs_rate = tk.StringVar()
items_for_listbox = ["Musik", "Sprache", "Vortrag", "Spr.+Vor.", "Sport"]
frame = tk.Frame(self)
frame.pack(pady=20)
self.dimension = tk.Frame(frame)
self.dimension.pack(side='left', pady=5)
tk.Label(self, text="Page 2", font=LARGE_FONT).pack(pady=10, padx=10)
tk.Label(self.dimension, textvariable=self.abs_rate).pack()
tk.Label(self.dimension, textvariable=self.s).pack()
tk.Label(self.dimension, textvariable=self.selected_var).pack(expand='yes')
tk.Label(self.dimension, textvariable=self.result_var).pack(expand='yes')
listbox_frame = tk.Frame(self.dimension)
listbox_frame.pack(expand='yes')
self.mylistbox = tk.Listbox(listbox_frame, height=5, width=10, font=('times', 18))
self.mylistbox.bind('<<ListboxSelect>>', self.select)
self.mylistbox.grid(row=0, column=0)
self.mylistbox.insert('end', *items_for_listbox)
scroll = tk.Scrollbar(listbox_frame, orient='vertical') # the alignment of the scrollbar
self.mylistbox["yscrollcommand"] = scroll.set # link the list with the scroll
scroll["command"] = self.mylistbox.yview # link the scroll with the scroll
scroll.grid(row=0, column=1, sticky='ns') # sticky=N+S+E)
tk.Button(self.dimension, text="Fläche der Absorber", command=self.calc).pack(expand='yes')
ttk.Button(self, text="Start Page", command=lambda: controller.show_frame(StartPage)).pack()
ttk.Button(self, text="Page 1", command=lambda: controller.show_frame(PageOne)).pack()
ttk.Button(self, text="Page 2", command=lambda: controller.show_frame(PageTwo)).pack()
ttk.Button(self, text="pasvariable", command=self.pass_variable).pack()
ttk.Button(self, text="pass absorption rate", command=self.absorptions_rate).pack()
def curselection(self, a):
if a == "Musik":
return 0.45 * math.log10(self.Pages.p) + 0.07
elif a == "Sprache":
return 0.37 * math.log10(self.Pages.p) - 0.14
elif a == "Vortrag":
return 0.32 * math.log10(self.Pages.p) - 0.17
elif a == "Spr.+Vor.":
return 0.26 * math.log10(Pages.p) - 0.14
elif a == "Sport":
return 0.75 * math.log10(Pages.p) - 1
def calc(self):
if self.mylistbox.get('active'):
abs_fl_ges = 0.163 * Pages.p / Pages.z
absorber = abs_fl_ges - Pages.abs_flä
self.result_var.set(absorber)
elif Pages.z == 0:
messagebox.showinfo("No selection")
def select(self, _=None):
a = self.mylistbox.get('anchor')
self.Pages.z = self.curselection(a)
self.selected_var.set(self.Pages.z)
def pass_variable(self):
self.s.set("volume: % .2f m³" % self.Pages.p)
def absorptions_rate(self):
self.abs_rate.set("volume: % .2f m³" % self.Pages.abs_flä)
if __name__ == '__main__':
ReverberationTime().mainloop()
Related
I am creating 2048 game on python with tkinter but I have a issue
I don't know what is wrong in left, right, up and down methods created in PageOne class.
In another class (StartPage), bind function calls these methods but this don't work
So I don't know how toresolve the mistakes, in bind functions or in the left, right, up and down methods?
In particular I get this error when I press the right key:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\fabio\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "C:\Users\fabio\PycharmProjects\2048gametk\2048gametk.py", line 198, in right
self.reverse()
AttributeError: 'Event' object has no attribute 'reverse'
And similar error for the other key (up, left and down):
Traceback (most recent call last):
File "C:\Users\fabio\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "C:\Users\fabio\PycharmProjects\2048gametk\2048gametk.py", line 208, in up
self.transpose()
AttributeError: 'Event' object has no attribute 'transpose'
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\fabio\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
TypeError: PageOne.left() missing 1 required positional argument: 'event'
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\fabio\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "C:\Users\fabio\PycharmProjects\2048gametk\2048gametk.py", line 218, in down self.transpose()
AttributeError: 'Event' object has no attribute 'transpose'
The left one is different because i put event instead of event = None as argument in the left module.
A small problem concern the score_frame that appears also in the StartPage and not only in the PageOne, so i don't know how to combine the frames on the code
Below you can find the entire code
Can anyone help me?
Thanks in advance
import os
import random
import sys
import tkinter as tk
from math import floor
class MyButton(tk.Button):
def __init__(self, *args, **kwargs):
tk.Button.__init__(self, *args, **kwargs, bg='brown', fg='white',
font="Helvetica 12 bold", width=8, pady='1m')
self.pack(pady="3m")
class Game(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title("2048 game")
self.dim = 4
self.main_grid = None
container = tk.Frame(self, width=500, height=600)
container.grid(pady=(100, 0))
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
self.bind("<Left>", PageOne.left)
self.bind("<Right>", PageOne.right)
self.bind("<Up>", PageOne.up)
self.bind("<Down>", PageOne.down)
self.mainloop()
def show_frame(self, controller): #page_name al posto di controller
frame = self.frames[controller]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.dim = controller.dim
label = tk.Label(self, text="2048", font="Helvetica 48 bold", fg="orange")
label.pack(side="top", fill="x")
button1 = MyButton(self, text="3x3", command=self.dim_3)
button1.pack()
button1.bind("<Return>", self.dim_3)
button2 = MyButton(self, text="4x4", command=self.dim_4)
button2.focus_force()
button2.pack()
button2.bind("<Return>", self.dim_4)
button3 = MyButton(self, text="5x5", command=self.dim_5)
button3.pack()
button3.bind("<Return>", self.dim_5)
button4 = MyButton(self, text="8x8", command=self.dim_8)
button4.pack()
button4.bind("<Return>", self.dim_8)
def dim_3(self):
self.dim = 3
self.controller.show_frame(PageOne)
def dim_4(self):
self.dim = 4
self.controller.show_frame(PageOne)
def dim_5(self):
self.dim = 5
self.controller.show_frame(PageOne)
def dim_8(self):
self.dim = 8
self.controller.show_frame(PageOne)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.matrix = None
self.score = None
self.cells = []
for i in range(self.controller.dim):
row = []
for j in range(self.controller.dim):
cell_frame = tk.Frame(self, bg="light grey",
width=500 / self.controller.dim, height=500 / self.controller.dim)
cell_frame.grid(row=i+10, column=j, padx=10 / self.controller.dim, pady=10 / self.controller.dim)
cell_number = tk.Label(self, bg="light grey")
cell_number.grid(row=i+10, column=j)
cell_data = {"frame": cell_frame, "number": cell_number}
row.append(cell_data)
self.cells.append(row)
score_frame = tk.Frame(controller.main_grid)
score_frame.place(relx=0.5, y=50, anchor="center")
tk.Label(score_frame, text="Score", font="Helvetica 18 bold").grid(row=0)
self.score_label = tk.Label(score_frame, text="0", font="Helvetica 24 bold")
self.score_label.grid(row=1)
self.start_game()
def start_game(self):
self.matrix = [[0] * self.controller.dim for _ in range(self.controller.dim)]
row = random.randint(0, self.controller.dim - 1)
col = random.randint(0, self.controller.dim - 1)
self.matrix[row][col] = 2
self.cells[row][col]["frame"].configure(bg="white")
self.cells[row][col]["number"].configure(bg="white", fg="black", font="Helvetica 24 bold", text="2")
while self.matrix[row][col] != 0:
row = random.randint(0, self.controller.dim - 1)
col = random.randint(0, self.controller.dim - 1)
self.matrix[row][col] = 2
self.cells[row][col]["frame"].configure(bg="white")
self.cells[row][col]["number"].configure(bg="white", fg="black", font="Helvetica 24 bold", text="2")
self.score = 0
# move all numbers on the left side
def stack(self):
new_matrix = [[0] * self.controller.dim for _ in range(self.controller.dim)]
for i in range(self.controller.dim):
fill_pos = 0
for j in range(self.controller.dim):
if self.matrix[i][j] != 0:
new_matrix[i][fill_pos] = self.matrix[i][j]
fill_pos += 1
self.matrix = new_matrix
# sum numbers horizontally and combine equal numbers
def combine(self):
for i in range(self.controller.dim):
for j in range(self.controller.dim - 1):
if self.matrix[i][j] != 0 and self.matrix[i][j] == self.matrix[i][j + 1]:
self.matrix[i][j] *= 2
self.matrix[i][j + 1] = 0
self.score += self.matrix[i][j]
# this function reverses the order of each row
def reverse(self):
new_matrix = []
for i in range(self.controller.dim):
new_matrix.append([])
for j in range(self.controller.dim):
new_matrix[i].append(self.matrix[i][self.controller.dim - 1 - j])
self.matrix = new_matrix
def transpose(self):
new_matrix = [[0] * self.controller.dim for _ in range(self.controller.dim)]
for i in range(self.controller.dim):
for j in range(self.controller.dim):
new_matrix[i][j] = self.matrix[j][i]
self.matrix = new_matrix
def add_number(self):
if any(0 in row for row in self.matrix):
row = random.randint(0, self.controller.dim - 1)
col = random.randint(0, self.controller.dim - 1)
while self.matrix[row][col] != 0:
row = random.randint(0, self.controller.dim - 1)
col = random.randint(0, self.controller.dim - 1)
self.matrix[row][col] = random.choice([2, 2, 2, 2, 4])
def update_GUI(self):
for i in range(self.controller.dim):
for j in range(self.controller.dim):
cell_value = self.matrix[i][j]
if cell_value == 0:
self.cells[i][j]["frame"].configure(bg="light grey")
self.cells[i][j]["number"].configure(bg="light grey", text="")
else:
self.cells[i][j]["frame"].configure(bg=NUMBER_COLOR[cell_value])
self.cells[i][j]["number"].configure(bg=NUMBER_COLOR[cell_value], fg="black",
font="Helvetica 24 bold", text=str(cell_value))
self.score_label.configure(text=self.score)
self.update_idletasks()
self.game_over()
def left(self, event):
self.stack()
self.combine()
self.stack()
self.add_number()
self.update_GUI()
self.game_over()
def right(self, event=None):
self.reverse()
self.stack()
self.combine()
self.stack()
self.reverse()
self.add_number()
self.update_GUI()
self.game_over()
def up(self, event=None):
self.transpose()
self.stack()
self.combine()
self.stack()
self.transpose()
self.add_number()
self.update_GUI()
self.game_over()
def down(self, event=None):
self.transpose()
self.reverse()
self.stack()
self.combine()
self.stack()
self.reverse()
self.transpose()
self.add_number()
self.update_GUI()
def horiz_moves(self):
for i in range(self.controller.dim):
for j in range(self.controller.dim - 1):
if self.matrix[i][j] == self.matrix[i][j + 1]:
return True
return False
def vert_moves(self):
for i in range(self.controller.dim - 1):
for j in range(self.controller.dim):
if self.matrix[i][j] == self.matrix[i + 1][j]:
return True
return False
def number(self):
if self.controller.dim == 3:
return 8
elif self.controller.dim == 4:
return 2048
elif self.controller.dim == 5:
return 8192
else:
return 16384
def restart(self):
self.bind("<Return>", os.execl(sys.executable, sys.executable, *sys.argv))
def game_over(self):
tk.Frame(self).place(relx=0.5, rely=0.5, anchor="center")
if not any(0 in row for row in self.matrix) and not self.horiz_moves() and not self.vert_moves():
top = tk.Toplevel()
top.geometry("300x100")
top.title("toplevel")
l2 = tk.Label(top, text="Game Over\n What do you want do?",
fg="white", font="Helvetica 12 bold")
l2.pack()
tk.Button(top, text="Restart", bg="green",
fg="white", font="Helvetica 10 bold",
command=self.restart).pack(side='left')
tk.Button(top, text="Quit", bg="red",
fg='white', font="Helvetica 10 bold", command=self.bind("<Return>", quit)).pack(side="right")
elif any(self.number() in row for row in self.matrix):
top = tk.Toplevel()
top.geometry("180x100")
top.title("toplevel")
l2 = tk.Label(top, text="You Win!\n What do you want do?", font="Helvetica 12 bold")
l2.pack()
tk.Button(top, text="Restart", bg="green",
fg="white", font="Helvetica 10 bold",
command=self.restart).pack(side='left')
tk.Button(top, text="Quit", bg="red",
fg='white', font="Helvetica 10 bold", command=self.bind("<Return>", quit)).pack(side="right")
def savegame(self):
f = open("savedata", "w")
line1 = " ".join(
[str(self.matrix[floor(x / self.controller.dim)][x % self.controller.dim])
for x in range(0, self.controller.dim ** 2)])
f.write(line1 + "\n")
f.write(str(self.controller.dim) + "\n")
f.write(str(self.score))
f.close()
def loadgame(self):
# self.score
# self.dim
# self.matrix
f = open("savedata", "r")
mat = (f.readline()).split(' ', self.controller.dim ** 2)
self.controller.dim = int(f.readline())
self.score = int(f.readline())
for i in range(0, self.controller.dim ** 2):
self.matrix[floor(i / self.controller.dim)][i % self.controller.dim] = int(mat[i])
f.close()
NUMBER_COLOR = {
2: "#fcefe6",
4: "#f2e8cb",
8: "#f5b682",
16: "#f29446",
32: "#ff775c",
64: "#e64c2e",
128: "#ede291",
256: "#fce130",
512: "#ffdb4a",
1024: "#f0b922",
2048: "#fad74d",
4096: "brown",
8192: "silver",
16384: "gold"
}
def main():
Game()
if __name__ == "__main__":
main()
Replace the code with the following:
self.bind("<Left>", self.frames[PageOne].left)
self.bind("<Right>", self.frames[PageOne].right)
self.bind("<Up>", self.frames[PageOne].up)
self.bind("<Down>", self.frames[PageOne].down)
The reason for your odd behavior is that you try to reach instances variables and methods but on the level of a class. It's not easy to explain in a few words, but you should research the difference between class an regular methods, the purpose of self and of course the documentation for classes and instances
Update
In order to make your dimensions work you need to create your matrix after you defined the dimensions, not when you initialize your Frame. The shortest way to achive this, is to create a function that is called when your dimension is defined.
In your PageOne you would do something like:
...
self.cells = []
def create_matrix(self):
for i in range(self.controller.dim):
...
score_frame = tk.Frame(self.controller.main_grid) #add self.
...
call this function when the user has chosen by (e.g):
def dim_3(self):
self.controller.dim = 3 #use self.controller dim
self.controller.frames[PageOne].create_matrix() #call create_matrix
self.controller.show_frame(PageOne)
and while you use the variable in your controller the following is not effective:
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
#self.dim = controller.dim
#is not a link to your var self.dim stores whats in controller.dim
Update2
in order to make your quit and restart work and with little improvements I have changed your code below. The code is left as an exercise since I still try to figure out the rules of the game. Happy codeing!
def restart(self):
for widget in self.winfo_children():
widget.destroy()
self.cells = []
self.controller.show_frame(StartPage)
def game_over(self):
tk.Frame(self).place(relx=0.5, rely=0.5, anchor="center")
if not any(0 in row for row in self.matrix) and not self.horiz_moves() and not self.vert_moves():
geo_string = "300x100"
title = "Game Over!"
text = "Game Over\n What do you want do?"
self.message(geo_string,title,text)
elif any(self.number() in row for row in self.matrix):
geo_string = "180x100"
title = "Congratulation!"
text = "You Win!\n What do you want do?"
self.message(geo_string,title,text)
def message(self, geo_string,title,text):
top = tk.Toplevel()
top.geometry(geo_string)
top.title(title)
l2 = tk.Label(top, text=text, font="Helvetica 12 bold")
l2.pack()
rbutton = tk.Button(top, text="Restart", bg="green",
fg="white", font="Helvetica 10 bold",
command=self.restart)
rbutton.bind('<ButtonRelease-1>',lambda e: self.controller.after(20,top.destroy))
rbutton.pack(side='left')
qbutton = tk.Button(top, text="Quit", bg="red",
fg='white', font="Helvetica 10 bold",
command=self.controller.destroy)
qbutton.pack(side="right")
I can't set the value and, after, run my function with my select radio. Someone can help me?
When i click the button for show me the functions "rendafixa" and "rendavariavel", nothing happens. but it was supposed to show me the "funfou rf" or "funfou rv".
How can i fix this?
from tkinter import *
class Application:
def __init__(self, master=None):
self.fonttitulo = ('Arial', '15', 'bold',)
self.fonttxt = ('Calibri', '10', 'bold')
self.fontent = ('Calibri', '9')
self.ctntitulo = Frame(master)
self.ctntitulo['padx'] = 20
self.ctntitulo['pady'] = 5
self.ctntitulo.pack()
self.ctnsubtitle = Frame(master)
self.ctnsubtitle['padx'] = 20
self.ctnsubtitle['pady'] = 5
self.ctnsubtitle.pack()
self.ctnnome = Frame(master)
self.ctnnome['padx'] = 20
self.ctnnome['pady'] = 5
self.ctnnome.pack()
self.ctnrsptnome = Frame(master)
self.ctnrsptnome['padx'] = 20
self.ctnrsptnome['pady'] = 5
self.ctnrsptnome.pack()
self.ctnqstnativo = Frame(master)
self.ctnqstnativo['padx'] = 20
self.ctnqstnativo['pady'] = 5
self.ctnqstnativo.pack()
self.ctnativo = Frame(master)
self.ctnativo['padx'] = 20
self.ctnativo['pady'] = 5
self.ctnativo.pack()
self.ctnslctativo = Frame(master)
self.ctnslctativo['padx'] = 20
self.ctnslctativo['pady'] = 5
self.ctnslctativo.pack()
self.ctnrandom = Frame(master)
self.ctnrandom['padx'] = 20
self.ctnrandom['pady'] = 5
self.ctnrandom.pack()
self.title = Label(self.ctntitulo, font = self.fonttitulo, text="Ganhos Futuros", width=40)
self.title.pack()
self.subtitle = Label(self.ctnsubtitle, font=self.fonttxt, text='Seu ajudante de investimentos', width=30)
self.subtitle.pack()
self.lblnome = Label(self.ctnnome, text='Qual seu nome? ', font=self.fonttxt, width=20)
self.lblnome.pack(side=LEFT)
self.entnome = Entry(self.ctnnome, textvariable = '', font=self.fontent, width=10)
self.entnome.pack(side=LEFT)
self.rsptnome = Label(self.ctnrsptnome, text="", width=30, font=self.fonttxt)
self.radioValue = IntVar()
self.radioValue.set(1)
self.btnnome = Button(self.ctnnome, text="Vamos lá!", font=self.fonttxt, width=10)
self.btnnome['command'] = self.aparecer_ativos
self.btnnome.pack(side=LEFT)
self.lblativos = Label(self.ctnqstnativo, text="Selecione seu ativo", font=self.fonttxt, width=20)
def aparecer_ativos(self):
self.nome = self.entnome.get()
self.rsptnome.config(text="Deixa eu te ajudar, {}!".format(self.nome))
self.rsptnome.pack()
self.lblativos.pack()
self.radio_one = Radiobutton(self.ctnativo, text="Renda Fixa", variable = self.radioValue, value = 1)
self.radio_two = Radiobutton(self.ctnativo, text="Renda Variável", variable = self.radioValue, value = 2)
self.radio_one.pack(side=LEFT)
self.radio_two.pack(side=LEFT)
self.lblrandom = Label(self.ctnrandom, text='', width=10, font=self.fonttxt)
self.btnslctativo = Button(self.ctnslctativo, text='Confirmar', width=10, command=self.qual_ativo)
self.btnslctativo.pack()
def qual_ativo(self):
self.ativozin = self.radioValue.get()
if self.ativozin == 1:
return self.rendafixa
if self.ativozin == 2:
return self.rendavariavel
def rendafixa(self):
self.lblrandom.config(text='funfou rf')
self.lblrandom.pack()
def rendavariavel(self):
self.lblrandom.config(text='funfou rv')
self.lblrandom.pack()
root = Tk()
Application(root)
root.mainloop()
So, how can I display my function "rendafixa" or "rendavariavel" on accordingly my radioValue?
I want to navigate to different pages of the GUI and on some pages, I need a timer if the timer expires then it will automatically redirect the user to Startpage. or if the user navigate then also timer will stop and the user will land on another page. The problem is that the timer of other pages is running in background and randomly takes user to start page. I am not able to figure out how to solve this
The code I developed is as follows:
import os
from itertools import cycle
import PIL.ImageTk, PIL.Image
import tkinter.font as font
import tkinter as tk
from tkinter import ttk
from tkinter.ttk import *
from tkinter import *
from tkinter import messagebox
import time
from time import sleep
from threading import Thread
LARGEFONT = ("Roboto", 35)
directory = r"C:\Users\mojave\tkinter\bg_images"
images = []
for filename in os.listdir(directory):
if filename.endswith(".jpg"):
images.append(os.path.join(directory,filename))
else:
continue
print(images)
#images = ["bg1.jpg", "bg2.jpg", "bg3.jpg"]
photos = cycle(PIL.ImageTk.PhotoImage(file=image) for image in images)
class tkinterApp(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.geometry('%dx%d' % (1366, 768))
self.frames = {}
for F in (StartPage, Page1, Page2):
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()
frame.event_generate("<<ShowFrame>>")
def get_page(self, page_class):
return self.frames[page_class]
# 1 second(s)
class StartPage(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
self.photo = PhotoImage(file = r"recycle_icon.png")
self.photoimage = self.photo.subsample(20,20)
btnFont = font.Font(family='Roboto',size=32,weight='bold')
#app.geometry('%dx%d' % (1366, 768))
global displayCanvas
displayCanvas = ttk.Label(self)
displayCanvas.place(x=0,y=0)
self.after(10,lambda: slideShow())
label = ttk.Label(self,text="StartPage", font=LARGEFONT)
label.grid(row=0, column=4, padx=10, pady=10)
button1 = ttk.Button(self,text="Page 1", command=lambda: controller.show_frame(Page1))
button1.grid(row=1, column=1, padx=10, pady=10)
button2 = ttk.Button(self, text = "page 2",
command = lambda : controller.show_frame(Page2))
button2.grid(row = 2, column = 1,padx = 10,pady = 10)
start_btn = tk.Button(self,text="\nStart Recycle",height=650, width=300,image=self.photoimage,
compound= TOP, command=lambda: controller.show_frame(Page1), activebackground="green", background="red", foreground="white", bd=5)
start_btn['font'] = btnFont
#start_btn.pack(side=TOP)
start_btn.place(x=1010,y=60)
self.bind("<<ShowFrame>>", self.on_show_frame)
def on_show_frame(self,event):
print("start page is shown..")
class Page1(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
#label = ttk.Label(self, text = "Page 1", font = LARGEFONT)
#label.grid(row = 0,column = 4,padx = 10,pady = 10)
lang_btnFont = font.Font(family='Roboto',size=32,weight='bold')
self.photo = PhotoImage(file = r"recycle_icon.png")
self.photoimage = self.photo.subsample(20,20)
self.img1 = PIL.ImageTk.PhotoImage(file=r'C:\\Users\\mojave\\tkinter\\bg_image.jpg')
displayCanvas1 = ttk.Label(self)
displayCanvas1.config(image=self.img1)
displayCanvas1.place(x=0,y=0)
lang_btn = tk.Button(self,text="English",height=300,
width=300,image=self.photoimage,compound=TOP, command= lambda : controller.show_frame(Page2),
activebackground= "green",background="red",foreground="white")
lang_btn['font'] = lang_btnFont
lang_btn.place(x=1010,y=60)
lang_btn2 = tk.Button(self,text="हिन्दी",height=300, width=300,image=self.photoimage,compound=TOP,
command= lambda : controller.show_frame(Page2), activebackground=
"green",background="red",foreground="white")
lang_btn2['font'] = lang_btnFont
lang_btn2.place(x=1010,y=400)
button1 = ttk.Button(self, text ="StartPage",image=self.photoimage,command= lambda :
controller.show_frame(StartPage))
button1.grid(row = 1, column = 1,padx = 10,pady = 10)
button2 = ttk.Button(self,text = "Page 2", command = lambda : controller.show_frame(Page2))
button2.grid(row = 2, column = 1,padx = 10,pady = 10)
self.timer_label1 = tk.Label(self,font = LARGEFONT, text="10s")
self.timer_label1.place(x=2,y=200)
self.timer_thread = Thread(target = self.on_show_frame)
self.timer_thread.start()
self.after(100,self.on_show_frame)
self.bind("<<ShowFrame>>", self.on_show_frame)
def on_show_frame(self,event=None):
print("page1 is shown..")
self.start = 10
self.temp = self.start
while self.temp >= 0:
self.timer_label1.config(text = str(self.temp)+ "s")
self.timer_label1.update()
if self.temp == 0:
self.timer_thread._is_running = False
show_frame_g(StartPage)
break
self.temp -=1
sleep(1)
class Page2(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self, parent)
label = ttk.Label(self,text = "Page 2", font = LARGEFONT)
label.grid(row = 0,column = 4,padx=10,pady = 10)
self.img1 = PIL.ImageTk.PhotoImage(file=r'C:\\Users\\mojave\\tkinter\\bg_image2.jpg')
displayCanvas1 = ttk.Label(self)
displayCanvas1.config(image=self.img1)
displayCanvas1.place(x=0,y=0)
button1 = ttk.Button(self, text = "Page 1",command = lambda : controller.show_frame(Page1))
button1.grid(row = 1,column = 1, padx = 10,pady = 10)
button2 = ttk.Button(self,text="Start Page", command = lambda : controller.show_frame(StartPage))
button2.grid(row = 2, column = 1,padx = 10, pady = 10)
self.bind("<<ShowFrame>>", self.on_show_frame)
def on_show_frame(self,event):
print("page2 is shown..")
#self.after(10000,lambda : show_frame_g(StartPage))
app = tkinterApp()
show_frame_g = app.show_frame
#def time_update():
# onTime_page2 =+ 1
def slideShow():
img = next(photos)
displayCanvas.config(image=img)
app.after(1000,slideShow) #after 1s
app.mainloop()
The problem is that the timer of other pages is running in background and randomly takes user to start page. I am not able to figure out how to solve this
The code I show hereunder has got some if statements which make different variables which all involve money. When I run the code I can select how many of any drink and if it is takeaway or not.
IF it iss takeaway it adds 5% to the cost and if there are more than 3 drinks it takes 10% off the invoice.
Could anyone help me add a +$ for the takeaway on the output area of gui and a -$ for the discount.
Any help would be appreciated.
If anyone wants to see the entire code, it is visible in this gist
import tkinter as tk
import time
import random
root = tk.Tk()
root.geometry("1600x8000")
root.title("Cafe au Lait")
tops = tk.Frame(root, width=1600, relief="sunken")
tops.pack(side="top")
f1 = tk.Frame(root, width=800, height=700, relief="sunken")
f1.pack(side="left")
latte = tk.DoubleVar()
double_expresso = tk.DoubleVar()
iced = tk.DoubleVar()
cost = tk.DoubleVar()
cappacuino = tk.DoubleVar()
expresso = tk.DoubleVar()
flat_white = tk.DoubleVar()
total = tk.DoubleVar()
takeaway_var = tk.StringVar()
rand = tk.IntVar()
discount = tk.DoubleVar()
takeaway = tk.DoubleVar()
def ref(even=None):
x=random.randint(10000,99999)
randomRef=str(x)
rand.set(randomRef)
global total, cost
if latte.get() == "":
col = 0
else:
col = latte.get()
if iced.get() == "":
coi = 0
else:
coi = iced.get()
if flat_white.get() == "":
cofw = 0
else:
cofw = flat_white.get()
if double_expresso.get() == "":
code = 0
else:
code = double_expresso.get()
if cappacuino.get() == "":
coc = 0
else:
coc = cappacuino.get()
if expresso.get() == "":
coe = 0
else:
coe = expresso.get()
costoflatte = col * 3.5
costoficed = coi * 2.5
costofflat_white = cofw * 3.75
costofdouble_expresso = code * 4.25
costofcappacuino = coc * 3.75
costofexpresso = coe * 3
total.set('{}'.format(cost.get() + costoflatte + costoficed + costofflat_white + costofdouble_expresso + costofcappacuino + costofexpresso))
cost.set('{}'.format(cost.get() + costoflatte + costoficed + costofflat_white + costofdouble_expresso + costofcappacuino + costofexpresso))
if txt_takeaway.get() in ['Yes', 'yes', 'y', 'Y']:
w = total.get()
takeaway.set(w * 0.05)
if txt_takeaway.get() in ['Yes', 'yes', 'y', 'Y']:
x = total.get()
total.set((x * 0.05) + x)
if (coc + col + coi + cofw + code + coe) >=3:
z = total.get()
discount.set(z * 0.1)
if (coc + col + coi + cofw + code + coe) >=3:
y = total.get()
total.set(y * 0.9)
The code above sets it all up so that the code below outputs corrdctly. It is needed to run. The first 2 buttons below are the ones that need the +$ and -$ added to.
lbl_takeaway= tk.Label(f1, font=('arial', 16, 'bold'),text="Takeaway",bd=16,anchor="w").grid(row=2, column=2)
txt_takeaway=tk.Entry(f1, font=('arial',16,'bold'),textvariable=takeaway,bd=10,insertwidth=4,bg="powder blue",justify='right')
txt_takeaway.grid(row=2,column=3)
lbl_discount= tk.Label(f1, font=('arial', 16, 'bold'),text="Discount",bd=16,anchor="w").grid(row=3, column=2)
txt_discount=tk.Entry(f1, font=('arial',16,'bold'),textvariable=discount,bd=10,insertwidth=4,bg="powder blue",justify='right')
txt_discount.grid(row=3,column=3)
tk.Label(f1, font=('arial', 16, 'bold'),text="Order Number",bd=16,anchor="w").grid(row=0, column=2)
txt_order=tk.Entry(f1, font=('arial',16,'bold'),textvariable=rand,bd=10,insertwidth=4,bg="powder blue",justify='right')
txt_order.grid(row=0,column=3)
tk.Label(f1, font=('arial', 16, 'bold'), text="Takeaway", bd=16, anchor="w").grid(row=6, column=0)
txt_takeaway = tk.Entry(f1, font=('arial',16,'bold'),textvariable=takeaway_var, bd=10, insertwidth=4, bg="powder blue", justify='right')
txt_takeaway.grid(row=6, column=1)
tk.Label(f1, font=('arial', 16, 'bold'), text="Cost of Order", bd=16, anchor="w").grid(row=1, column=2)
txt_cost = tk.Entry(f1, font=('arial',16,'bold'), textvariable=cost,bd=10, insertwidth=4, bg="powder blue", justify='right')
txt_cost.grid(row=1, column=3)
tk.Label(f1, font=('arial', 16, 'bold'), text="Total Cost", bd=16, anchor="w").grid(row=5, column=2)
txt_totalcost = tk.Entry(f1, font=('arial',16,'bold'), textvariable=total, bd=10, insertwidth=4, bg="powder blue", justify='right')
txt_totalcost.grid(row=5, column=3)
tk.Label(f1, font=('arial', 16, 'bold'),text="Latte",bd=16,anchor="w").grid(row=1, column=0)
txt_latte=tk.Entry(f1, font=('arial',16,'bold'),textvariable=latte,bd=10,insertwidth=4,bg="powder blue",justify='right')
txt_latte.grid(row=1,column=1)
btnTotal=tk.Button(f1,padx=16,pady=8,bd=16,fg="black",font=('arial',16,'bold'),width=10,text="Total",bg="powder blue",command=ref).grid(row=7,column=1)
root.bind("<Return>", ref)
root.mainloop()
You can insert a default value in the entry field; here is a little example that subclasses tk.Entry, that you can reuse in your own project:
import tkinter as tk
class EntryBoxWithNegativeDollarSign(tk.Entry):
def __init__(self, master, *args, **kwargs):
self.master = master
super().__init__(self.master, *args, **kwargs)
self.default = '-$'
self.insert(0, self.default)
self.pack()
def set_default(self):
self.delete('0',tk.END)
self.insert(0, self.default)
def get(self):
value = - float(super().get()[2:])
self.set_default()
print(value)
return value
root = tk.Tk()
app = tk.Frame(root)
app.pack()
entry = EntryBoxWithNegativeDollarSign(app)
tk.Button(app, text='get value', command=entry.get).pack()
root.mainloop()
I am attempting to make a basic study clock as a learning exercise for Tkinter but I get an error when attempting run it saying self is not defined. Here is the error message.
Traceback (most recent call last):
File "productivityclock.py", line 6, in <module>
class gui(object):
File "productivityclock.py", line 113, in gui
while 0 < self.z:
NameError: name 'self' is not defined
Here is my code, I would really appreciate if someone could help me out, Thanks
from Tkinter import *
import time
root = Tk()
class gui(object):
def __init__(self, master):
self.frame = Frame(master)
self.frame.pack()
t_int = 0
b_int = 0
reps = 0
self.menu()
def menu(self):
self.button1 = Button(
self.frame, text="Set Time", command = self.set_time)
self.button2 = Button(
self.frame, text="Set Breaks", command = self.set_break)
self.button3 = Button(
self.frame, text="Set Intervals", command = self.set_reps)
self.button4 = Button(
self.frame, text="Start", command = self.timer)
self.button1.pack(side = LEFT)
self.button2.pack(side = LEFT)
self.button3.pack(side = LEFT)
self.button4.pack(side = LEFT)
def set_time(self):
self.button1.pack_forget()
self.button2.pack_forget()
self.button3.pack_forget()
self.button4.pack_forget()
self.l = Label(self.frame, text = "Enter the time of each study session (minutes)")
self.button = Button(
self.frame, text="Get", command=self.on_button1)
self.entry = Entry(self.frame)
self.button.pack(side = RIGHT)
self.entry.pack(side = LEFT)
self.l.pack(side = LEFT)
def set_break(self):
self.button1.pack_forget()
self.button2.pack_forget()
self.button3.pack_forget()
self.button4.pack_forget()
self.l = Label(self.frame, text = "Enter the time of each break (minutes)")
self.button = Button(
self.frame, text="Get", command=self.on_button2)
self.entry = Entry(self.frame)
self.button.pack(side = RIGHT)
self.entry.pack(side = LEFT)
self.l.pack(side = LEFT)
def set_reps(self):
self.button1.pack_forget()
self.button2.pack_forget()
self.button3.pack_forget()
self.button4.pack_forget()
self.l = Label(self.frame, text = "Enter the amount of study sessions (minutes)")
self.button = Button(
self.frame, text="Get", command=self.on_button3)
self.entry = Entry(self.frame)
self.button.pack(side = RIGHT)
self.entry.pack(side = LEFT)
self.l.pack(side = LEFT)
def on_button1(self):
x = self.entry.get()
self.t_int = x
print self.t_int
self.button.pack_forget()
self.entry.pack_forget()
self.l.pack_forget()
self.menu()
def on_button2(self):
x = self.entry.get()
self.b_int = x
print self.b_int
self.button.pack_forget()
self.entry.pack_forget()
self.l.pack_forget()
self.menu()
def on_button3(self):
x = self.entry.get()
self.reps = x
print self.reps
self.button.pack_forget()
self.entry.pack_forget()
self.l.pack_forget()
self.menu()
def timer(self):
x = self.t_int
y = self.b_int
self.z = self.reps
while 0 < self.z:
while x > 0:
time.sleep(60)
n = Label(self.frame, text = "You have %r minutes left in your session") % x
n.pack(side = LEFT)
x = x - 1
n.pack_forget
while y > 0:
time.sleep(60)
self.e = Label(self.frame, text = "You have %r minutes left in your break") % y
self.e.pack(side = LEFT)
self.y = self.y - 1
self.e.pack_forget()
z = z - 1
x = self.t_int
y = self.b_int
app = gui(root)
root.mainloop()
Yes, at line 113, while 0 < self.z: is not properly indented, and all the lines below it.