私はPythonの基礎を知っていると思っていましたが、この問題はそれが間違っていることを証明しているようです.
問題は、クラスを関数に渡すと、その関数は渡されたクラスを認識せず、代わりにその親クラスを認識するだけです。
これがクラスです。
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()
これは別のクラスで、上記のクラスによってメソッドが呼び出されます。上記のクラスは自分自身を引数として渡します。
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
問題は、2 番目のクラスの行 master = gui.get_master() でエラーが発生することです。なぜなら、AttributeError: 'Frame' object has no attribute 'get_master' Frame がクラス Gui の親であるためです。