我无法在Python 2.7中通过Tkinter传递父变量

时间:2019-09-17 08:53:55

标签: python inheritance tkinter

首先,我必须说我是Python的初学者,因此我的代码可能显得多余或混乱。 我编写了由两个都属于tkinter框架的类组成的代码。类ExportGUI继承自Hdf5GUI,并由函数export调用。问题是我试图通过子功能访问父变量datasetsfilter,但是它不起作用:

# Parent class

class Hdf5GUI(GUI):

    def __init__(self,hdf5w,master):

        # Frame definition
        self.master = master # parent root
        self.hdf5w = hdf5w #root
        self.hdf5w.title('Hdf5 Reader') 
        self.hdf5w.rowconfigure(0,weight=1)
        self.hdf5w.columnconfigure(0,weight=1)
        self.hdf5w.columnconfigure(1,weight=1)

        self.frameDataset = Frame(self.hdf5w,padx=5,pady=5)
        self.frameDataset.grid(row=0,column=0,sticky='wesn')
        self.frameDataset.rowconfigure(1,weight=1)
        self.frameDataset.columnconfigure(0,weight=1)

        self.datasetpath_button = Button(self.frameDataset,text="Export dataset path",command = self.exportDatasetPath)
        self.datasetpath_button.grid(row=0,column=0,columnspan=2,pady=5,sticky='nwe')

        self.dataset_scrollbar = Scrollbar(self.frameDataset)
        self.dataset_scrollbar.grid(row=1,column=1,sticky='esn')

        self.dataset_listbox = Listbox(self.frameDataset,exportselection=0)
        self.dataset_listbox.grid(row=1,column=0,sticky='wesn')
        self.dataset_listbox.bind('<<ListboxSelect>>', self.onSelectDataset)

        self.dataset_listbox.config(yscrollcommand=self.dataset_scrollbar.set)
        self.dataset_scrollbar.config(command=self.dataset_listbox.yview)

        self.datatype_scrollbar = Scrollbar(self.frameDataset)
        self.datatype_scrollbar.grid(row=2,column=1,sticky='esn')

        self.datatype_listbox = Listbox(self.frameDataset,selectmode='extended',exportselection=0)
        self.datatype_listbox.grid(row=2,column=0,sticky='wesn')
#        self.dataset_listbox.bind('<<ListboxSelect>>', self.onSelectDataset)
#        
        self.datatype_listbox.config(yscrollcommand=self.datatype_scrollbar.set)
        self.datatype_scrollbar.config(command=self.datatype_listbox.yview)        



        self.frameFilter = Frame(self.frameDataset)
        self.frameFilter.grid(row=3,column=0,sticky='wen')
        self.frameFilter.columnconfigure(0,weight=1)
        self.frameFilter.columnconfigure(1,weight=1)
        self.frameFilter.columnconfigure(2,weight=1)
        self.frameFilter.columnconfigure(3,weight=1)

        self.filter_label = Label(self.frameFilter,text="Dataset filter")
        self.filter_label.grid(row=0,column=0,columnspan=4,sticky='wen')

        self.filter0 = Listbox(self.frameFilter,exportselection=0)
        self.filter0.grid(row=1,column=0,sticky='wen')
        self.filter0.bind('<<ListboxSelect>>', self.onSelectFilter0)

        self.filter1 = Listbox(self.frameFilter,exportselection=0)
        self.filter1.grid(row=1,column=1,sticky='wen')
        self.filter1.bind('<<ListboxSelect>>', self.onSelectFilter1)

        self.filter2 = Listbox(self.frameFilter,exportselection=0)
        self.filter2.grid(row=1,column=2,sticky='wen')
        self.filter2.bind('<<ListboxSelect>>', self.onSelectFilter2)

        self.filter3 = Listbox(self.frameFilter,exportselection=0)
        self.filter3.grid(row=1,column=3,sticky='wen')

        self.frameFile = Frame(self.hdf5w,padx=5,pady=5)
        self.frameFile.grid(row=0,column=1,sticky='wesn')
        self.frameFile.rowconfigure(1,weight=1)
        self.frameFile.columnconfigure(0,weight=1)

        self.folderPath_button = Button(self.frameFile,text="Open files in directory",command=self.exportFiles)
        self.folderPath_button.grid(row=0,column=0,columnspan=2,pady=5,sticky='wen')

        self.files_listbox = Listbox(self.frameFile,selectmode='extended',exportselection=0)
        self.files_listbox.grid(row=1,column=0,sticky='wesn')

        self.files_scrollbar = Scrollbar(self.frameFile)
        self.files_scrollbar.grid(row=1,column=1,sticky='esn')

        self.files_listbox.config(yscrollcommand=self.files_scrollbar.set)
        self.files_scrollbar.config(command=self.files_listbox.yview)

        self.displayData_button = Button(self.frameFile, text="display dataset", command=self.displayData)
        self.displayData_button.grid(row=2,column=0,columnspan=2,padx=10,pady=5,sticky='wen')


        self.displayTxt_button = Button(self.frameFile, text="Export", command=self.export)
        self.displayTxt_button.grid(row=2,column=1,columnspan=2,padx=10,pady=5,sticky='wen')



#        self.lblFrame = LabelFrame()


        self.hdf5w.protocol("WM_DELETE_WINDOW", self.onClosing)





        self.hdf5w.mainloop()

    def exportDatasetPath(self):

        self.dataset_listbox.delete(0,'end')
        self.filter0.delete(0,'end')
        self.filter1.delete(0,'end')
        self.filter2.delete(0,'end')
        self.filter3.delete(0,'end')

        self.ohdf5 = Hdf5()

        print(self.ohdf5.loadcase_label_list)

        i = 0
        for dataset in self.ohdf5.datasets:
            self.dataset_listbox.insert(i,dataset)
            i+=1

        i = 0
        for item in self.ohdf5.filter0:
            self.filter0.insert(i,item)
            i+=1

    def onSelectDataset(self,evt):

        self.datatype_listbox.delete(0,'end')
        index = self.dataset_listbox.curselection()[0]
        datasetPath = self.dataset_listbox.get(index)

        self.odataset = self.ohdf5.getDataset(datasetPath)

        i=0
        for col in self.odataset.columns:
            self.datatype_listbox.insert(i,col)
            i+=1


    def onSelectFilter0(self,evt):

        self.dataset_listbox.delete(0,'end')
        self.filter1.delete(0,'end')
        self.filter2.delete(0,'end')
        self.filter3.delete(0,'end')

        index = self.filter0.curselection()[0]
        item0 = self.filter0.get(index)


        if item0 == 'NASTRAN':
            i = 0
            for dataset in self.ohdf5.datasets:
                self.dataset_listbox.insert(i,dataset)
                i+=1

        else:

            self.ohdf5.setFilterGroupPath(item0)
            self.ohdf5.setFilterGroup(self.ohdf5.filterGroupPath)

            i = 0
            self.datasetsfilter = self.ohdf5.getDatasets(self.ohdf5.filterGroupPath)
            for dataset in self.datasetsfilter:
                self.dataset_listbox.insert(i,dataset)
                i+=1

            i = 0
            for item in self.ohdf5.filter1:
                self.filter1.insert(i,item)
                i+=1

    def onSelectFilter1(self,evt):

        self.dataset_listbox.delete(0,'end')
        self.filter2.delete(0,'end')
        self.filter3.delete(0,'end')

        index = self.filter0.curselection()[0]
        item0 = self.filter0.get(index)
        index = self.filter1.curselection()[0]
        item1 = self.filter1.get(index)

        self.ohdf5.setFilterGroupPath(item0,item1)
        self.ohdf5.setFilterGroup(self.ohdf5.filterGroupPath)

        i = 0
        self.datasetsfilter = self.ohdf5.getDatasets(self.ohdf5.filterGroupPath)
        print(self.datasetsfilter)
        for dataset in self.datasetsfilter:
            self.dataset_listbox.insert(i,dataset)
            i+=1

        i = 0
        for item in self.ohdf5.filter2:
            self.filter2.insert(i,item)
            i+=1

    def onSelectFilter2(self,evt):

        self.dataset_listbox.delete(0,'end')
        self.filter3.delete(0,'end')

        index = self.filter0.curselection()[0]
        item0 = self.filter0.get(index)
        index = self.filter1.curselection()[0]
        item1 = self.filter1.get(index)
        index = self.filter2.curselection()[0]
        item2 = self.filter2.get(index)

        self.ohdf5.setFilterGroupPath(item0,item1,item2)
        self.ohdf5.setFilterGroup(self.ohdf5.filterGroupPath)

        i = 0
        self.datasetsfilter = self.ohdf5.getDatasets(self.ohdf5.filterGroupPath)
        print(self.datasetsfilter)
        for dataset in self.datasetsfilter:
            self.dataset_listbox.insert(i,dataset)
            i+=1

        i = 0
        for item in self.ohdf5.filter3:
            self.filter3.insert(i,item)
            i+=1

    def exportFiles(self):

        self.files_listbox.delete(0,'end')

        title = 'Choose the working HDF5 directory where there are *.h5 files :'
        Tk().withdraw()
        dirname_root = askdirectory(initialdir=os.getcwd(), title = title)

        self.filePath_list = []

        for folders, subfolders,files in os.walk(dirname_root):
            for f in files:
                ext = os.path.splitext(f)[1]
                if ext == '.h5': self.filePath_list.append(os.path.join(folders,f))

        i = 0
        for path in self.filePath_list:
            self.files_listbox.insert(i,os.path.basename(path))
            i+=1

    def onClosing(self):

#        if tkMessageBox.askokcancel("Quit", "Do you want to quit?"):
        self.hdf5w.destroy()
        self.show(self.master)  

    def displayData(self):
        print('function dislaying datas')
        datas =   self.datatype_listbox.curselection()
        print(datas)
        new_window = Toplevel(self.frameFile)
        w = DisplayDataGUI(new_window, self.odataset, datas)

    def get_datasetsfilter(self):
        return self.datasetsfilter

    def export(self):
        new_window2 = Toplevel(self.frameFile)
        w = ExportGUI(self.hdf5w,new_window2)

所以直到现在我的代码都可以正常工作,但是我必须使用在ExportGUI中调用的其他函数来完成程序。例如export_filter

#==============================================================================
# Child class   
#==============================================================================



class ExportGUI(Hdf5GUI): 

    def __init__(self,hdf5w, master):

        self.master = master
        self.master.title("Export")
        self.master.geometry('200x200')

        label = Label(self.master, text="Choose the kind of export")
        label.place(x=20, y=0)

        export_selected = Button(self.master, text = 'Export filters',command=self.export_filter)
        export_selected.place(x=20, y=50)

        self.master.mainloop()   

    def export_filter(self):    
        print(self.ohdf5.datatsetsfilter)

但是我遇到了以下错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda2\lib\lib-tk\Tkinter.py", line 1542, in __call__
    return self.func(*args)
  File "GUI\GUI.py", line 397, in export_filter
    print(self.ohdf5.datatsetsfilter)
AttributeError: 'ExportGUI' object has no attribute 'ohdf5'

ohdf5未知datatsetsfilterExportGUI(我对self.datatsetsfilter有相同的错误)。 考虑到此代码无效,我尝试使用super函数。我在get_datasetsfilter中创建了一个函数Hdf5GUI

 def get_datasetsfilter(self):
        return self.datasetsfilter

然后在ExportGUI中调用它(我在{2.7中添加了__metaclass__ = type来修复类型prblm):

def export_filter(self):    
        super(ExportGUI, self).get_datasetsfilter

我承认我看到了Super的许多其他示例,但它们似乎都用在__init__方法中。但是,它仍然不起作用。我现在想知道错误是由于对继承或tkinter的理解不正确造成的。

1 个答案:

答案 0 :(得分:1)

问题在于您已经从父类覆盖了__init__方法。通常,您首先从父类中调用__init__方法,该方法可以使用super()进行访问。因此,您的代码应类似于:

class ExportGUI(Parent_Class):

    def __init__(self, hdf5w, master):
        super().__init__(hdf5w, master)
        self.master = master
        self.master.title("Export")
        self.master.geometry('200x200')

更新:

现在您已经清除了某些详细信息,我可以扩大此答案。请注意,现在从__init__进行的ExportGUI调用中使用了两个传递的参数,分别为hdf5wmaster,成功调用{{1}时需要第一个}来自父类。因此,您需要在创建__init__实例的Parent_Class定义中更改代码,以便为hdf5w传递适当的值-我想是,您想要从父类传递值:

ExportGUI

我不禁注意到,传递给def export(self): new_window2 = Toplevel(self.frameFile) w = ExportGUI(self.hdf5w, new_window2) 的参数Parent_Class.__init__hdf5w并未在任何地方使用。也许您想将它们保存在变量中,例如:

master

如果这些相同并且应该传递给class Parent_Class(GUI): def __init__(self,hdf5w,master): self.hdf5w = hdf5w self.master = master ,则可以在ExportGUI的{​​{1}}函数中创建实例时将它们简单地传递。如果不需要它们并决定删除它们,请确保修改export的{​​{1}}调用以及Parent_Class中的__init__调用。< / p>