Random tkinter window opening on if/else statement - python

I'm wondering if I got my if else statement wrong or if its a tkinter issue. I want it so that if a 0 is left in any or all boxes, it gives an error message. But after the error message is closed, it opens a random blank window. This is my code. The specific area is the if else statement within the function valueget()
import tkinter as tk
def mainwindow():
mainwindow = tk.Tk()
mainwindow.title('Enter values')
mainwindow.geometry('160x110')
mainwindow.config(bg='#aaf0d1')
tk.Label(mainwindow, text = 'Enter a', font = ('verdana'), bg='#aaf0d1').grid(row=0)
tk.Label(mainwindow, text = 'Enter b', font = ('verdana'), bg='#aaf0d1').grid(row=1)
tk.Label(mainwindow, text = 'Enter c', font = ('verdana'), bg='#aaf0d1').grid(row=2)
getA = tk.IntVar()
aBox = tk.Entry(mainwindow, textvariable = getA, width=3, bg='#aaf0d1')
aBox.grid(row=0, column=1)
aBox.config(highlightbackground='#aaf0d1')
getB = tk.IntVar()
bBox = tk.Entry(mainwindow, textvariable = getB, width=3, bg='#aaf0d1')
bBox.grid(row=1, column=1)
bBox.config(highlightbackground='#aaf0d1')
getC = tk.IntVar()
cBox = tk.Entry(mainwindow, textvariable = getC, width=3, bg='#aaf0d1')
cBox.grid(row=2, column=1)
cBox.config(highlightbackground='#aaf0d1')
button = tk.Button(mainwindow, text='Obtain roots', command = lambda: valueget(), font = ('verdana'), highlightbackground='#aaf0d1')
button.grid(row=4)
button.config(bg='#aaf0d1')
def valueget():
readA = getA.get()
readB = getB.get()
readC = getC.get()
intA = int(readA)
intB = int(readB)
intC = int(readC)
negroot = (readB**2)-(4*readA*readC)
quadformulaplus = (-readB + (pow(negroot,0.5)))/(2*readA) #quad forumla
quadformulaminus = (-readB - (pow(negroot,0.5)))/(2*readA) #quad forumla
messagewindow = tk.Tk()
messagewindow.geometry('290x50')
messagewindow.title('Roots of the equation')
messagewindow.config(bg='#aaf0d1')
if readA == 0 or readB==0 or readC==0 or (readA==0 and readB==0 and readC==0):
errorwindow = tk.messagebox.showerror(message='none').pack()
else:
label = tk.Label(messagewindow, text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}', bg='#aaf0d1', font = ('verdana'))
label.grid(row=1)
closebutton = tk.Button(messagewindow, text='Close', command = lambda: messagewindow.destroy(), font = ('verdana'), highlightbackground='#aaf0d1')
closebutton.grid(row=2)
closebutton.config(bg='#aaf0d1')
messagewindow.mainloop()
# print(f'the roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}')
mainwindow.mainloop()
def startup():
startpage = tk.Tk()
startpage.title('Solver')
photo = tk.PhotoImage(file = r"/Users/isa/Desktop/DiffEqns/cover.png") #image load
coverbutton = tk.Button(startpage, image = photo, command = lambda: [startpage.destroy(), mainwindow()])
coverbutton.pack()
coverbutton.configure(highlightbackground='#aaf0d1')
startpage.mainloop()
startup()

Here's a basic idea of what I would do:
import tkinter as tk
from tkinter import messagebox
def mainwindow(root):
# Creates a toplevel window
mainwindow = tk.Toplevel()
mainwindow.protocol("WM_DELETE_WINDOW", root.destroy) # This overrides the "X" being clicked to also destroy the root window.
root.withdraw() # "Hides" the root window, leaving it (and mainloop) running in the background.
mainwindow.title('Enter values')
mainwindow.geometry('160x110')
mainwindow.config(bg='#aaf0d1')
# Since all three of the labels/entries are the same
# we can save space by generating them in a loop
entry_items = ('Enter a', 'Enter b', 'Enter c')
values = []
for x, item in enumerate(entry_items): # Using enumerate and x to assign rows
tk.Label(mainwindow, text = item,
font = ('verdana'), bg='#aaf0d1').grid(row=x) # Row assigned to x.
values.append(tk.StringVar()) # Appended StringVar to list.
tk.Entry(mainwindow,
textvariable = values[-1], # Uses the last value appended to the values list.
highlightbackground='#aaf0d1',
width=3,
bg='#aaf0d1').grid(row=x, column=1) # Row assigned to x.
tk.Button(mainwindow,
text='Obtain roots',
command = lambda vals = values: valueget(vals), # Here the button command is assigned with the values list
font = ('verdana'), bg='#aaf0d1',
highlightbackground='#aaf0d1').grid(row=3) # we know there are 3 items before this.
mainwindow.lift() # This is a method of bringing a window to the front
def valueget(vals):
# This line gets the values from the StringVars, converts them to ints,
# and returns them to their respective variables.
try:
readA, readB, readC = [int(val.get()) for val in vals]
except ValueError:
messagebox.showerror(title="Number Error", message='Values must be numbers')
return
# Here the variables are checked to see if they are 0
# Since each one is being checked if it is 0, there is no need to check if they are all 0.
for val in (readA, readB, readC):
if val == 0:
# If they are 0, shows an error message
messagebox.showerror(title="Zero Error", message='Values must not be zero')
return
# Creates a toplevel to display the results
messagewindow = tk.Toplevel()
messagewindow.title('Roots of the equation')
messagewindow.config(bg='#aaf0d1')
negroot = (readB**2)-(4*readA*readC)
quadformulaplus = (-readB + (pow(negroot,0.5)))/(2*readA) #quad forumla
quadformulaminus = (-readB - (pow(negroot,0.5)))/(2*readA) #quad forumla
tk.Label(messagewindow,
text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}',
bg='#aaf0d1',
font = ('verdana')).pack(padx = 5, pady = 2)
tk.Button(messagewindow,
text='Close',
command = messagewindow.destroy, # There is no need for a lambda for this.
font = ('verdana'),
bg = '#aaf0d1',
highlightbackground='#aaf0d1').pack(padx = 5, pady = 2)
# print(f'the roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}')
messagewindow.lift() # This is a method of bringing a window to the front
def startup():
startpage = tk.Tk()
startpage.title('Solver')
# COMMENTED OUT FOR TESTING
#photo = tk.PhotoImage(file = r"/Users/isa/Desktop/DiffEqns/cover.png") #image load
coverbutton = tk.Button(startpage,
# COMMENTED OUT FOR TESTING
#image = photo,
text = "TESTING", # HERE FOR TESTING
highlightbackground='#aaf0d1',
command = lambda root = startpage: mainwindow(root)).pack() # Passes the startpage to the mainwindow function.
startpage.mainloop() # The only mainloop you need.
startup()

I would recommend to improve the readability of the if-else statement for a start.
coefficients = [readA, readB, readC]
if sum(coefficients): # If they all are all zeros this will be False
if min(coefficients): # If any one is zero, this will be False
label = tk.Label(messagewindow, text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}', bg='#aaf0d1', font = ('verdana'))
label.grid(row=1)
closebutton = tk.Button(messagewindow, text='Close', command = lambda: messagewindow.destroy(), font = ('verdana'), highlightbackground='#aaf0d1')
closebutton.grid(row=2)
closebutton.config(bg='#aaf0d1')
else:
errorwindow = tk.messagebox.showerror(message='none').pack()
else:
errorwindow = tk.messagebox.showerror(message='none').pack()

Related

Python tkinter how to get value from an entry box

I am trying to make a little thing in python like JOpenframe is java and I'm trying to make an entry box. That works fine but when I try to get the value and assign it to variable "t" nothing works. This is what I have:
def ButtonBox(text):
root = Tk()
root.geometry("300x150")
t = Label(root, text = text, font = ("Times New Roman", 14))
t.pack()
e = Entry(root, borderwidth = 5, width = 50)
e.pack()
def Stop():
root.destroy()
g = e.get()
ok = Button(root, text = "OK", command = Stop)
ok.pack()
root.mainloop()
t = ButtonBox("f")
I've tried to make "g" a global variable but that doesn't work. I have no idea how to get the value from this, and I'm hoping someone who does can help me out. Thanks!
If you want to return the value of the entry box after ButtonBox() exits, you need to:
initialize g inside ButtonBox()
declare g as nonlocal variable inside inner function Stop()
call g = e.get() before destroying the window
Below is the modified code:
from tkinter import *
def ButtonBox(text):
g = "" # initialize g
root = Tk()
root.geometry("300x150")
t = Label(root, text = text, font = ("Times New Roman", 14))
t.pack()
e = Entry(root, borderwidth = 5, width = 50)
e.pack()
def Stop():
# declare g as nonlocal variable
nonlocal g
# get the value of the entry box before destroying window
g = e.get()
root.destroy()
ok = Button(root, text = "OK", command = Stop)
ok.pack()
root.mainloop()
# return the value of the entry box
return g
t = ButtonBox("f")
print(t)

Python Tkinter mixing radio and default user input box in canvas?

I like to mixed my radio button selection with a few user input boxes.
I managed to output them separately but I can't combine them due to the one using canvas1.pack and another using row.pack.
This is my first radio button interface where user will select Auto or Manual and there is a box for user to input stock symbols manually.
This interface by default will show the default parameters such as volume or dividend amount and the user can change this parameter.
When I tried to put them together, they overlaps. The stock symbol input box was also shifted down. How can I move the parameter boxes below the auto and manual radio button without shifting the stock symbol box to the bottom?
Below is a sample of my code that is ready to be executed on jupyter.
from tkinter import *
from tkinter import simpledialog
from tkinter import messagebox
import tkinter as tk
#default filter values
parameter1 = 100000
parameter2 = 3
global answer
global user_list
# Prepare parameters
fields = ['Min. parameter1', 'Min. parameter2', 'Min. 3parameter3',
'Min. parameter4','Min. parameter5', 'Max. parameter6']
default_values = [parameter1,parameter2,parameter3,parameter4,
parameter5,parameter6]
captured_values = []
def on_closing():
if messagebox.askokcancel("Quit", "Do you want to quit?"):
root.destroy()
sys.stdout = orig_stdout
f.close()
sys.exit("Application closed by user")
def makeform(root, fields,default_values):
entries = {}
for i in range(len(fields)):
row = tk.Frame(root)
lab = tk.Label(row, width=24, text=fields[i]+": ", anchor='w')
ent = tk.Entry(row)
ent.insert(0, default_values[i])
row.pack(side=tk.TOP,
fill=tk.X,
padx=5,
pady=5)
lab.pack(side=tk.LEFT)
ent.pack(side=tk.RIGHT,
expand=tk.YES,
fill=tk.X)
entries[fields[i]] = ent
return entries
# Button click event
def btn_click (e):
global answer
answer_choice = rdo_var.get()
answer = rdo_txt[answer_choice]
global user_list
user_list = entry1.get()
captured_values.append(e['Min. parameter1'].get())
captured_values.append(e['Min. parameter2'].get())
captured_values.append(e['Min. parameter3'].get())
captured_values.append(e['Min. parameter4'].get())
captured_values.append(e['Min. parameter5'].get())
captured_values.append(e['Max. parameter6'].get())
root.destroy()
return answer
# Generate Tk class
root = tk.Tk()
# Screen size
root.geometry ('270x250')
# Screen title
root.title ('Enter parameters')
# set default parameters
ents = makeform(root, fields, default_values)
# box for manual input
canvas1 = tk.Canvas(root, width = 350, height = 400)
canvas1.pack()
entry1 = tk.Entry (root)
canvas1.create_window(165, 45, window=entry1)
# List radio button labels
rdo_txt = ['Auto','Manual']
# Radio button status
rdo_var = tk.IntVar ()
# Create and place radio buttons dynamically
for i in range (len (rdo_txt)):
rdo = Radiobutton (root, value = i, variable = rdo_var, text = rdo_txt [i])
rdo.place (x = 20, y = 15 + (i * 20))
# Create button
confirm_button = tk.Button (root, text = 'Confirm', command = (lambda e=ents: btn_click(e)))
confirm_button.place (x = 180, y = 200)
root.protocol("WM_DELETE_WINDOW", on_closing)
root.mainloop ()
if(answer == 'Manual'):
print('Manual run selected.')
manual_run = 1
temp_user_list = []
user_list = user_list.split(',')
for i in range(len(user_list)):
temp_user_list.append(user_list[i].strip().upper())
print('Symbol(s) entered : ' + str(temp_user_list))
else:
manual_run = 0
print('Auto run selected.')
# new captured values
parameter1 = float(captured_values[0])
parameter2 = float(captured_values[1])
Here is an expanded answer.
Complete code example.
from tkinter import *
from tkinter import simpledialog
from tkinter import messagebox
import tkinter as tk
#default filter values
parameter1 = 100000
parameter2 = 2
parameter3 = 3
parameter4 = 4
parameter5 = 5
parameter6 = 6
global answer
global user_list
# Prepare parameters
fields = ['Min. parameter1', 'Min. parameter2', 'Min. parameter3',
'Min. parameter4','Min. parameter5', 'Max. parameter6']
default_values = [parameter1,parameter2,parameter3,parameter4,
parameter5,parameter6]
captured_values = []
def on_closing():
if messagebox.askokcancel("Quit", "Do you want to quit?"):
root.destroy()
sys.stdout = orig_stdout
f.close()
sys.exit("Application closed by user")
def makeform(root, fields,default_values):
entries = {}
for i in range(len(fields)):
row = tk.Frame(root)
lab = tk.Label(row, width=28, text=fields[i]+": ", anchor='e')
ent = tk.Entry(row)
ent.insert(0, default_values[i])
row.pack(side=tk.TOP,
fill=tk.X,
padx=5,
pady=5)
lab.pack(side=tk.LEFT)
ent.pack(side=tk.RIGHT,
expand=tk.YES,
fill=tk.X)
entries[fields[i]] = ent
return entries
# Button click event
def btn_click (e):
global answer
answer_choice = rdo_var.get()
answer = rdo_txt[answer_choice]
global user_list
user_list = entry1.get()
captured_values.append(e['Min. parameter1'].get())
captured_values.append(e['Min. parameter2'].get())
captured_values.append(e['Min. parameter3'].get())
captured_values.append(e['Min. parameter4'].get())
captured_values.append(e['Min. parameter5'].get())
captured_values.append(e['Max. parameter6'].get())
root.destroy()
return answer
# Generate Tk class
root = tk.Tk()
# Screen size
root.geometry("410x260")
# Screen title
root.title('Enter parameters')
# set default parameters
ents = makeform(root, fields, default_values)
# box for manual input
manual = makeform(root, ['Manual input'], ["Enter value here"])
entry1 = manual["Manual input"]
entry1["background"] = "yellow" # make it standout
del manual
# List radio button labels
rdo_txt = ['Auto','Manual']
# Radio button status
rdo_var = tk.IntVar()
# Create and place radio buttons dynamically
for i in range (len (rdo_txt)):
rdo = Radiobutton (root, value = i, variable = rdo_var, text = rdo_txt [i])
rdo.place (x = 20, y = 15 + (i * 20))
# Create button
confirm_button = tk.Button (root, text = 'Confirm', command = (lambda e=ents: btn_click(e)))
confirm_button.place (x = 205, y = 220)
root.protocol("WM_DELETE_WINDOW", on_closing)
root.mainloop()
if(answer == 'Manual'):
print('Manual run selected.')
manual_run = 1
temp_user_list = []
user_list = user_list.split(',')
for i in range(len(user_list)):
temp_user_list.append(user_list[i].strip().upper())
print('Symbol(s) entered : ' + str(temp_user_list))
else:
manual_run = 0
print('Auto run selected.')
# new captured values
parameter1 = float(captured_values[0])
parameter2 = float(captured_values[1])

tkinter GUI Text Box is not displaying all results similar to terminal output

I am trying to make a loan amortization table inside tkinter GUI using text box. However, all the loan amortization table is fully displayed in the terminal console as an output.
The tkinter text BOX output display's only the last line: Here is the full code:
import math
import tkinter as tk
from tkinter import *
def calcLoanPayment(p, r, n, t):
if p > 0 and r > 0 and n > 0 and t > 0:
clp = (p *(r/n)*(pow(1 + r/n, n * t)))/(pow(1 + r/n, n * t)-1)
clp = round(clp, 2)
return clp
else:
return -1
def runApp(): #This will bound the function runapp to the calcbtn.
print("running")
p = principalentry.get() #this will get value as a string
try:
p = float(p) #this will make cast it to float variable.
except:
p = -1
principalentry.delete(0, END) #this will clear the entry after calculation
r = interestrateentry.get()
try: #Try will help from crushing the program when wrong value entered
r = float(r)
except:
r = -1
interestrateentry.delete(0, END) #this will clear the entry after calculation
n = compoundintervalentry.get() #this will get value as a string
try:
n = int(n) #this will make cast it to float variable.
except:
n = -1
compoundintervalentry.delete(0, END) #this will clear the entry after calculation
t = durationentry.get()
try: #Try will help from crushing the program when wrong value entered
t = int(t)
except:
t = -1
durationentry.delete(0, END) #this will clear the entry after calculation
clp = calcLoanPayment(p,r,n,t)
print(clp)
paymentinterval = n*t
paymentinterval = int(paymentinterval)
startingBalance=p
endingBalance=p
for i in range(1, paymentinterval+1):
interestcharge =r/n*startingBalance
endingBalance=startingBalance+interestcharge-clp
result ="\t\t"+str(i)+"\t\t" +str(round (startingBalance, 1)
)+"\t\t"+str(round (interestcharge, 1))+"\t\t"+str(round (clp, 1)
)+"\t\t"+str(round (endingBalance, 1))
startingBalance = endingBalance
print(result)
finaloutput = result
output.config(state="normal")
output.delete(0.0, 'end')
output.insert(END, finaloutput)
output.config(state="disabled")
#Frontend maincode Startshere:
#sketch the design of the user interface first.
root = tk.Tk()
root.config(bg="#F8B135")
root.state("zoomed")
#There are 3 steps to build event programming
#Step 1: construct the widgets
#step 2: configure the widget to make it nicer
#srep 3: place or pack the widget in the root window
title = Label(root, text = "Loan Payment Calculator", font = 'bold')
title.config(fg='white', bg="#28348A")
title.pack(fill = BOTH)
principallabel = Label(root, text="Principal: ")
principallabel.config(anchor = W, font = 'bold', bg="#F8B135")
principallabel.place(x=50, y=30)
principalentry = Entry(root)
principalentry.config(bg="#ffffff")
principalentry.place(x=400, y=30)
interestratelabel = Label(root, text="Interest Rate: enter as Decimal (eg.2% as 0.02) ")
interestratelabel.config(anchor = W, font = 'bold', bg="#F8B135")
interestratelabel.place(x=50, y=70)
interestrateentry = Entry(root)
interestrateentry.config(bg="#ffffff")
interestrateentry.place(x=400, y=70)
compoundintervallabel = Label(root, text="Compound Interval: ")
compoundintervallabel.config(anchor = W, font = 'bold', bg="#F8B135")
compoundintervallabel.place(x=50, y=110)
compoundintervalentry = Entry(root)
compoundintervalentry.config(bg="#ffffff")
compoundintervalentry.place(x=400, y=110)
durationlabel = Label(root, text="Duration: ")
durationlabel.config(anchor = W, font = 'bold', bg="#F8B135")
durationlabel.place(x=50, y=150)
durationentry = Entry(root)
durationentry.config(bg="#ffffff")
durationentry.place(x=400, y= 150)
output = Text(root)
output.config(width= 150, height = 100, bg="white", state="disabled", borderwidth=2, relief= "groove", wrap='word')
output.place(x=50, y=230)
calcbtn = Button(root, text= "Calculate", font = 'bold', highlightbackground="#3E4149")
calcbtn.config(fg='#28348A',command=runApp)
calcbtn.place(x=50, y=190)
root. mainloop()
file.close()`
I couldn't figure out How to display the whole output like the terminal did on the tkinter textbox output function. your help is much appreciated.
There are 2 small changes to the code in the function runApp()
output.config(state="normal")
# output.delete(0.0, 'end') # This line deletes the last entry in the text box. Remove this
output.insert(END, finaloutput + '\n') # Add a newline here. Generates the desired 'tabular' output
output.config(state="disabled")

TypeError: 'float' object has no attribute '__getitem__'. (Python)

import Tkinter
import tkMessageBox
from Tkinter import *
CanvasHeight = 500
CanvasWidth = 600
Canvas width and height set to 10x the maximum of the variables.
IsGraphHidden = 0
MainWindow = Tkinter.Tk()
This is the window for all the sliders, and is defined as "MainWindow" for later use.
Strength = DoubleVar()
Multiple = DoubleVar()
Time = DoubleVar()
All of the variables set to DoubleVar, because of the Tkinter plugin.
It needs it's own special floats, integers and strings to work.
They can be accessed as normal variables by using VARIABLE.get()
coords = []
lastcoords = [0,0]
This is what we'll use to continue the line instead of just having a bunch of lines drawing themselves from the corner of the screen.
Plot = DoubleVar()
StrengthScale = Scale( MainWindow, variable = Strength, orient = HORIZONTAL,label="Strength")
MultipleScale = Scale( MainWindow, variable = Multiple, from_ = float(0), to = float(1), resolution = float(0.01), orient = HORIZONTAL, label="Multiple")
TimeScale = Scale( MainWindow, variable = Time, orient = HORIZONTAL, from_ = int(0), to = int(120), label="Time")
These are the procedures for the buttons, as well as the rest of the code.
def Calculate():
answer = float(Strength.get())*float(Multiple.get())
tkMessageBox.showinfo("Answer:", answer)
def PrepPlot():
global IsGraphHidden
global coords
global lastcoords
lastcoords0 = lastcoords[0]
lastcoords1 = lastcoords[1]
coords.append(lastcoords0)
coords.append(lastcoords1)
coords.append(Time.get()*5)
coords.append(Strength.get()*Multiple.get()*5)
lastcoords = Time.get()*5
lastcoords = Strength.get()*Multiple.get()*5
if IsGraphHidden == 0:
Graph = Canvas(MainWindow, width = CanvasWidth, height = CanvasHeight, bg = "white")
Graph.create_line(coords, fill = "black")
Graph.grid(row=5, column=1)
else:
Graph.destroy()
Graph.delete("all")
Graph.create_line(coords, fill = "black")
Graph.grid(row=5,column=1)
IsGraphHidden = 1
def DisplayPoints():
PointWindow = Tkinter.Tk()
Text = Label(PointWindow, textvariable = "Hi there", relief=RAISED)
Text.pack()
PointWindow.mainloop() #Work in progress, nothin' to see here.
Button = Tkinter.Button(MainWindow, text= "Calculate",command = Calculate)
PrepButton = Tkinter.Button(MainWindow, text = "Plot", command = PrepPlot) #The text is the text on the button.
DisplayButton = Tkinter.Button(MainWindow, text = "Display Plots", command = DisplayPoints)
MultipleScale.grid(row=0,column=0)
StrengthScale.grid(row=1,column=0)
TimeScale.grid(row=1,column=2)
PrepButton.grid(row=2,column=1)
Button.grid(row=4,column=1)
DisplayButton.grid(row=3,column=1)
MainWindow.mainloop()
I need some help with the float object getitem error, I'm doing this code for work experience at Manchester university...
You replaced the lastcoords list with a floating point value:
lastcoords = Time.get()*5
lastcoords = Strength.get()*Multiple.get()*5
so that next time around the line:
lastcoords0 = lastcoords[0]
raises your exception as you cannot use subscription on a floating point value.
I think you wanted to set a new list instead:
lastcoords = [Time.get() * 5, Strength.get() * Multiple.get() * 5]

Passing the current class trouble

I thought I know the fundamentals of python, but this problem seems to prove that wrong.
Problem is, when I pass a class to a function, that function will not recognize the class that I passed, but instead just recognize that parent class.
This is the class.
from tkinter import *
from one_sample_t_test_dialog import One_T_Test_Dialog
from about_us_dialog import About_Us_Dialog
class Gui(Frame):
def __init__(self, master):
Frame.__init__(self, master, background="white")
self._master = master
# Main Window
frame = Frame(master, width = 800, height = 600)
self._master.title("Statistics Program")
# Menus
menu = Menu(master)
master.config(menu=menu)
# --Tests
test_menu = Menu(menu)
menu.add_cascade(label = "Tests", menu = test_menu)
# ----T-Tests
t_test_menu = Menu(test_menu)
test_menu.add_cascade(label = "T-Tests", menu = t_test_menu)
t_test_menu.add_command(label="One Sample t-test", command = self.one_sample_t_test)
t_test_menu.add_command(label="Two Sample t-test", command = self.two_sample_t_test)
t_test_menu.add_command(label="Paired t-test", command = self.about_us)
# --Help
help_menu = Menu(menu)
menu.add_cascade(label = "Help", menu = help_menu)
help_menu.add_command(label="About Us", command = self.about_us)
# Toolbar
# --t-test
toolbar = Frame(master)
l = Label(toolbar, text="Mean Comparison:")
l.pack(side=LEFT, padx = 5, pady = 5)
b=Button(toolbar, text = "One Sample t-test", command=self.one_sample_t_test)
b.pack(side=LEFT)
b=Button(toolbar, text = "Two Sample t-test", command=self.two_sample_t_test)
b.pack(side=LEFT)
b=Button(toolbar, text = "Paired t-test", command=self.two_sample_t_test)
b.pack(side=LEFT)
# --anova
l=Label(toolbar, text="ANOVA:")
l.pack(side=LEFT, padx = 5, pady = 5)
b=Button(toolbar, text = "One Way Anova", command=self.two_sample_t_test)
b.pack(side=LEFT)
# --Multiple-comparison Tests
toolbar_02 = Frame(master)
l=Label(toolbar_02, text="Multiple Mean Comparison:")
l.pack(side=LEFT, padx = 5, pady = 5)
b=Button(toolbar_02, text = "Tukey", command=self.two_sample_t_test)
b.pack(side=LEFT)
b=Button(toolbar_02, text = "Bonferroni", command=self.two_sample_t_test)
b.pack(side=LEFT)
toolbar.pack(fill=BOTH)
toolbar_02.pack(fill=BOTH)
# Spreadsheet.
self.canvas = canvas = Canvas(self._master)
self.canvas_frame = canvas_frame = Frame(canvas)
# Scrollbars
vbar=Scrollbar(self._master,orient=VERTICAL, command=self.canvas.yview)
hbar=Scrollbar(self._master,orient=HORIZONTAL, command=self.canvas.xview)
# Further configuration
canvas.configure(yscrollcommand=vbar.set, xscrollcommand=hbar.set)
# Initialize scrollbars
vbar.pack(side=RIGHT,fill=Y)
hbar.pack(side=BOTTOM,fill=X)
canvas.pack(side=LEFT, expand=True, fill="both")
canvas.create_window((4,4), window=canvas_frame, anchor="nw")
canvas_frame.bind("<Configure>", self.OnFrameConfigure)
self.grid()
#canvas_frame.pack()
self._master.geometry("800x600+50+50")
#self.pack(fill=BOTH, expand=1)
def get_master(self):
return self._master
def OnFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def about_us(self):
d = About_Us_Dialog(self._master)
root.wait_window(d.parent)
def grid(self):
"""
Make the grid here.
"""
grid_frame = self.canvas_frame
self.entry = []
for i in range(40):
self.entry.append([])
for i in range(len(self.entry)):
for j in range(80):
self.entry[i].append(Entry(grid_frame, width=10))
self.entry[i][j].grid(row=j, column=i)
# grid_frame.pack(padx=2, pady=2)
def one_sample_t_test(self):
d = One_T_Test_Dialog(self)
value = self._master.wait_window(d.parent)
# Check if an error occured.
result = None # We will store the result here.
if value is None:
return
else:
# perform the t-test here.
pass
# If we made it at this point, there's no error and
# the result have been acquired. We can now display
# the result.
def two_sample_t_test(self):
# Testing Ground
#print(self.get_variables())
#print(self.get_values(3))
pass
def get_variables(self):
"""
This method will return a dictionary of variable names and their corresponding
index, that is located in index zero of the double array. For instance,
self.entry[3][0] is a variable name, so is self.entry[5][0], and so on.
"""
variable_name_dict = {}
for i in range(len(self.entry)):
temp = self.entry[i][0].get()
if temp is not "":
variable_name_dict[i] = temp
return variable_name_dict
def get_values(self, variable_index):
"""
This method will return a list of values that is located under the variable.
Use this in conjunction with get_variables().
"""
values = []
if self.entry[variable_index][0] is not "": # Make sure that it's not empty.
for v in self.entry[variable_index]:
if v.get() is not "":
values.append(v.get())
# Since the first cell is in the column is always a variable name, we can
# pop the first element.
values.pop(0)
return values
root = Tk()
app = Gui(root)
root.mainloop()
This is the other class, with a method being called by the class above. the class above pass itself as an argument.
from tkinter import *
from tkinter import messagebox
import dialog
class One_T_Test_Dialog(dialog.Dialog):
def body(self, gui):
master = gui.get_master()
# Entry Labels.
Label(master, text="Mean:").grid(row=0)
Label(master, text="Standard Deviation:").grid(row=1)
Label(master, text="Sample Size:").grid(row=2)
Label(master, text="Sample Size:").grid(row=3)
Label(master, text="Test Value:").grid(row=4)
# Data entry class members.
# The for loop initialize the list as an entry list.
num_of_entry = 5
self.entry = [] #entry list
for i in range(num_of_entry):
self.entry.append(Entry(master))
# Data entry location initialization.
for i in range(num_of_entry):
self.entry[i].grid(row=i,column=1)
# Or, the user can just select a mean from the drop down list and
# enteryt the test value.
Label(master, text="Select Values Instead:").grid(column = 0, row=5)
self.dropdown_val = StringVar(master)
# initial value
self.dropdown_val.set('Select a values.')
choices = ['red', 'green', 'blue', 'yellow','white', 'magenta']
option = OptionMenu(master, self.dropdown_val, *choices).grid(column = 1, row=5)
button = Button(master, text="check value slected").grid(column=1, row=6)
# Further initialization.
# --At the Test Value, or null hypothesis, we want to have a default
# value. Assuming this is a 151/252 level course, the default value
# is always 0.
self.entry[4].insert(0, "0")
return self.entry[0] # initial focus
def apply(self):
# Collect the data first.
data_list = []
for e in self.entry:
data_list.append(e.get())
# Validate
for d in data_list:
# Make sure it's not empty.
# Make sure the value is float.
empty_flag = False
not_float_flag = False
if len(d) == 0:
empty_flag = True
if empty_flag is False:
try:
float(d)
except ValueError:
not_float_flag = True
if empty_flag is True or not_float_flag is True:
# Report an input error.
if empty_flag is True and not_float_flag is False:
messagebox.showerror("INPUT ERROR", "There's an empty input box.")
elif not_float_flag is True and empty_flag is False:
messagebox.showerror("INPUT ERROR", "Check your input. Make sure its a number.")
elif not_float_flag is True and empty_flag is True:
messagebox.showerror("INPUT ERROR", "There's an empty input box and non-numerical input.")
return None
# If everything went well, convert the validated data.
for i in range(len(data_list)):
data_list[i] = float(data_list[i])
return data_list
The problem is the line
master = gui.get_master()
in the second class gives an error because
AttributeError: 'Frame' object has no attribute 'get_master'
Frame being the parent of the class Gui.

Categories