I´ve been working on a bhaskara equation solver with Interface(tkinter) on python. I´ve watched some tutorials and I´ve split the Pages into classes. The basic idea of this application is the following:
It starts at StartPage
, where the user clicks on the select values button and this opens up PageOne
. At this page the user should type the desired values and click the select values button (I´m sorry, I couldn't find a way to save all the values at one, if you know how to do this too, please let me know). After the user saves the values, he goes back to StartPage
and clicks the Calculate button. If all values are OK, it shows the result
variable.
import tkinter as tk
from tkinter import ttk, END
import math
LARGE_FONT =("Verdana", 12)
def calculate():
global value_a
global value_b
global value_c
value_list = [value_a, value_b, value_c]
if "" in value_list:
return False
else:
delta = (int(value_b.get())**2) - 4*int(value_a.get())*int(value_c.get())
if delta >= 0:
delta_root = math.sqrt(delta)
bhask_pos = int(-value_b.get()) + (delta_root)/2*int(value_a.get())
bhask_neg = int(-value_b.get()) - (delta_root)/2*int(value_a.get())
global result
result = "The equation", int(value_a.get()), "x² +", int(value_b.get()), "x +", int(value_c.get()), "has the results ", int(bhask_pos), "and ", int(bhask_neg)
else:
pass
return True
class App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self,*args, **kwargs)
#self.geometry("720x360")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_columnconfigure(0, weight=1)
container.grid_rowconfigure(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)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
button = ttk.Button(self, text="Insert values", command=lambda: controller.show_frame(PageOne))
button.pack(side="top", padx=10, pady=20, expand=False)
canvas = tk.Canvas(self, width=400, height=200, bg="#C0C0C0", bd="10")
canvas.pack(side="bottom", padx=10, pady=20, expand=False)
if calculate() == False:
canvas.create_text(30, 30, text="Error. Check if you selected all values")
elif calculate() == True:
canvas.create_text(30, 30, text=result)
else:
pass
calculation_button = ttk.Button(self, text="Calculate", command=calculate)
calculation_button.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
def get_entry_data_a():
global value_1
value_1 = int(value_a.get())
entry_a.delete(0, END)
print(value_1)#just for debugging
def get_entry_data_b():
global value_2
value_2 = int(value_b.get())
entry_b.delete(0, END)
print(value_2)
def get_entry_data_c():
global value_3
value_3 = int(value_c.get())
entry_c.delete(0, END)
print(value_3)
def event_data_a(event):
value_1 = int(value_a.get())
entry_a.delete(0, END)
print(value_1)
def event_data_b(event):
value_2 = int(value_b.get())
entry_b.delete(0, END)
print(value_2)
def event_data_c(event):
value_3 = int(value_c.get())
entry_c.delete(0, END)
print(value_3)
text_a = tk.Label(self, text="value from a:", padx=10, pady=10)
text_a.grid(row=1, column=1)
text_b = tk.Label(self, text="value from b:", padx=10, pady=10)
text_b.grid(row=2, column=1)
text_c = tk.Label(self, text="value from c", padx=10, pady=10)
text_c.grid(row=3, column=1)
value_a = tk.IntVar()
entry_a = tk.Entry(self, textvariable=value_a)
entry_a.grid(row=1, column=2)
entry_a.delete(0, END)
button_a = ttk.Button(self, text="Save value", command=get_entry_data_a)
button_a.grid(row=1, column=3, padx=10, pady=10)
value_b = tk.IntVar()
entry_b = tk.Entry(self, textvariable=value_b)
entry_b.grid(row=2, column=2)
entry_b.delete(0, END)
button_b = ttk.Button(self, text="Save value", command=get_entry_data_b)
button_b.grid(row=2, column=3, padx=10, pady=10)
value_c = tk.IntVar()
entry_c = tk.Entry(self, textvariable=value_c)
entry_c.grid(row=3, column=2)
entry_c.delete(0, END)
button_c = ttk.Button(self, text="Save value", command=get_entry_data_c)
button_c.grid(row=3, column=3,padx=10, pady=10)
entry_a.bind("<Return>", event_data_a)
entry_b.bind("<Return>", event_data_b)
entry_c.bind("<Return>", event_data_c)
back_button = ttk.Button(self, text="Return to Start Page", command=lambda:controller.show_frame(StartPage))
back_button.grid(row=5, column=2, padx=20, pady=20)
app = App()
app.mainloop()
The results should appear in the canvas
, as well as a message error if the user does not select a value. My actual problem is that the canvas
object is created in StartPage
, so I need to define the function before the StartPage
class (because I need the boolean result returned from the function calculate()
to create the text in the canvas), but the actual values that the user chooses comes only at the end of the code. How is it possible to use those values? Where should I define the function calculate()
in this case?
This is the error message:
line 10, in calculate
value_list = [value_a, value_b, value_c]
NameError: name 'value_a' is not defined