tkinter,无法从其类外部调用函数



简单地说,我不能从程序中标记的问题区域调用filterCBO。它返回:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:AnacondaenvsSE_win64_py35libtkinter__init__.py", line 1550, in __call__
return self.func(*args)
File "<ipython-input-24-b9ade6a4c197>", line 116, in callFilters
Root.filterCBOs(self)
File "<ipython-input-24-b9ade6a4c197>", line 164, in filterCBOs
startDate = dt.datetime(year=int(self.fromDate.get()[2]),month=int(self.fromDate.get()[0]),day=int(self.fromDate.get()[1]))
AttributeError: 'Event' object has no attribute 'fromDate'

正如您所看到的,当在init中调用该函数时,以及当通过选择组合框值来调用该函数的时候,该函数都能正常工作。但是,当通过将enter键绑定到DateEntry中的条目字段来调用它时,它不起作用。我是新来的,所以我确信这与从另一个类中调用它有关,但我不知道如何绕过它。


#================================================================================
# Imports
#================================================================================
import os
import pandas as pd
import datetime as dt
import tkinter as tk
from tkinter import ttk
startTimestamp=dt.datetime.now()
print('Starting ' + str(startTimestamp))
#================================================================================
# User Changable Variables
#================================================================================
#signaturePath = r'T:Process DataEDMSignature Files'
#================================================================================
# Functions (mostly used to cleanup variables)
#================================================================================
#commented out because i ran this section once and saved to csv. saves me from indexing
#the directory during testing.   
'''
def indexDirectory():
#filenames use the following format:
# yyyy.mm.dd.hh.mm.tool.toolSN.feature.sfc.sig
df = pd.DataFrame(columns=['FullPath', 'Timestamp', 'Feature', 'Machine', 'Tool'])
for root, dirs, files in os.walk(signaturePath):
for file in files:
splitter = file.split('.')
if len(splitter) != 10: #weird filename
continue #skip to next file
date=dt.datetime.strptime(splitter[0]+'-'+splitter[1]+'-'+splitter[2]+' '+splitter[3]+':'+splitter[4],'%Y-%m-%d %H:%M')
df = df.append({'FullPath' : os.path.join(root, file), 
'Timestamp' : date, 
'Feature' : splitter[7], 
'Machine' : os.path.basename(root), 
'Tool' : splitter[5] + '_' + splitter[6] 
}, ignore_index=True)
return df
with open(r'C:Usersu1106710DesktopIndex.csv', 'w+') as SaTemp:
indexDirectory().to_csv(SaTemp, header=True, index=False)
'''

# Index available signature files to a dataframe
#sigIndex=indexDirectory
sigIndex=pd.read_csv(r'D:Tibbert4) ScriptsSignature AnalysisTempIndex.csv')
sigIndex['Timestamp'] = pd.to_datetime(sigIndex['Timestamp'])
#================================================================================
# Build GUI
#================================================================================
class DateEntry(tk.Frame):
def __init__(self, master, frame_look={}, **look):
args = dict(relief=tk.SUNKEN, border=1)
args.update(frame_look)
tk.Frame.__init__(self, master, **args)
args = {'relief': tk.FLAT}
args.update(look)
self.entry_1 = tk.Entry(self, width=2, **args)
self.label_1 = tk.Label(self, text='/', **args)
self.entry_2 = tk.Entry(self, width=2, **args)
self.label_2 = tk.Label(self, text='/', **args)
self.entry_3 = tk.Entry(self, width=4, **args)
self.entry_1.pack(side=tk.LEFT)
self.label_1.pack(side=tk.LEFT)
self.entry_2.pack(side=tk.LEFT)
self.label_2.pack(side=tk.LEFT)
self.entry_3.pack(side=tk.LEFT)
self.entries = [self.entry_1, self.entry_2, self.entry_3]
self.entry_1.bind('<KeyRelease>', lambda e: self._check(0, 2))
self.entry_2.bind('<KeyRelease>', lambda e: self._check(1, 2))
self.entry_3.bind('<KeyRelease>', lambda e: self._check(2, 4))
#PROBLEM HERE!
#self.entry_1.bind('<Return>', Root.filterCBOs)
#self.entry_2.bind('<Return>', Root.filterCBOs)
#self.entry_3.bind('<Return>', Root.filterCBOs)
def _backspace(self, entry):
cont = entry.get()
entry.delete(0, tk.END)
entry.insert(0, cont[:-1])
def _check(self, index, size):
entry = self.entries[index]
next_index = index + 1
next_entry = self.entries[next_index] if next_index < len(self.entries) else None
data = entry.get()
if len(data) > size or not data.isdigit():
self._backspace(entry)
if len(data) >= size and next_entry:
next_entry.focus()
def get(self):
return [e.get() for e in self.entries]

class Root(tk.Tk):
def __init__(self):
super(Root, self).__init__()
self.title("Filmcool Siganture Analysis")
self.minsize(width=800,height=600)
self.InitUI()
self.filterCBOs()
def InitUI(self):
#Setup Date Entry
self.fromDateLBL = tk.Label(self, text='Date Range')
self.fromDate = DateEntry(self)
self.toDateLBL = tk.Label(self, text='To')
self.toDate = DateEntry(self)
#Set Date Defaults
self.fromDate.entry_1.insert(0,'01')
self.fromDate.entry_2.insert(0,'01')
self.fromDate.entry_3.insert(0,'2014')
self.toDate.entry_1.insert(0,dt.date.today().month)
self.toDate.entry_2.insert(0,dt.date.today().day)
self.toDate.entry_3.insert(0,dt.date.today().year)
#Setup Feature Combobox
self.featureLBL = tk.Label(self, text='Feature')
self.featureCBO = ttk.Combobox(self, width=15)
self.featureCBO.bind('<<ComboboxSelected>>', self.filterCBOs)
#Setup Tool Combobox
self.toolLBL = tk.Label(self, text='Tool')
self.toolCBO = ttk.Combobox(self, width=15)
self.toolCBO.bind('<<ComboboxSelected>>', self.filterCBOs)
#Arrange UI Elements
self.fromDateLBL.grid(column=0,row=4)
self.fromDate.grid(column=1,row=4,sticky='e')
self.toDateLBL.grid(column=2,row=4,sticky='e')
self.toDate.grid(column=3,row=4)
self.featureLBL.grid(column=0, row=0, sticky='w')
self.featureCBO.grid(column=1, row=0)
self.toolLBL.grid(column=0, row=1, sticky='w')
self.toolCBO.grid(column=1, row=1)
def filterCBOs(self, event=None):
#Create and filter dataframe
df=sigIndex
#Filter by Date
#THROWS ERROR ON NEXT LINE
startDate = dt.datetime(year=int(self.fromDate.get()[2]),month=int(self.fromDate.get()[0]),day=int(self.fromDate.get()[1]))
endDate = dt.datetime(year=int(self.toDate.get()[2]),month=int(self.toDate.get()[0]),day=int(self.toDate.get()[1]))
print(startDate)
print(endDate)
df=df[(df['Timestamp'] >= startDate) & (df['Timestamp'] <= endDate)]
#Filter by Feature
if self.featureCBO.get() == "":
pass
else:
df=df[df['Feature'] == self.featureCBO.get()]
#Filter by Tool
if self.toolCBO.get() == "":
pass
else:
df=df[df['Tool'] == self.toolCBO.get()]
#print(df)
#Filter Feature CBO        
self.featureCBO['values'] = df['Feature'].unique().tolist()
self.featureCBO['values'] = (*self.featureCBO['values'], '') #add empty line to end
#Filter Tool CBO 
self.toolCBO['values'] = df['Tool'].unique().tolist()
self.toolCBO['values'] = (*self.toolCBO['values'], '') #add empty line to end


if __name__ == '__main__':
window = Root()
window.mainloop()
print('done')

问题在于尝试将函数引用为Root.filterCBO(. The function belongs to an instance of Root, so it needs to bemaster。filterCBOsincemaster `正在设置为根窗口。

self.entry_1.bind('<Return>', master.filterCBOs)

最新更新