-1

First of All, I have to say that I am a beginner in Python, so my code might appears redundant or muddled. I made this code which consists of two classes that are both tkinter frame. The class ExportGUI inherits from Hdf5GUI and is called by the function export. The thing is I am trying to access the parent variable datasetsfilter through a child function but it doesnt work :

# 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)

So until now my code perfectly works but I had to complete my program with some other functions that I call in ExportGUI. For example 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)

But I got the following error :

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'

Neither ohdf5 or datatsetsfilter is known by ExportGUI(I had the same error with self.datatsetsfilter). Considering this code didnt work I tried to use the super function. I created a function get_datasetsfilter in Hdf5GUI :

 def get_datasetsfilter(self):
        return self.datasetsfilter

and then called it in ExportGUI (I added __metaclass__ = type to fix type prblm in 2.7) :

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

I admit I saw many other exemple with Super but they all seems to be used in __init__ method. However, it still doesnt work. I am now wondering if the error results from my bad comprehension of inheritance or tkinter.

  • 1
    Where would you think `ohdf5` is defined? Perhaps you're missing a call to `super().__init__()`? – deceze Sep 17 '19 at 08:56
  • @deceze♦ Note that my entire parent class perfectly works and that `self.ohdf5 = Hdf5()`, I dont really know how to use `super()` could you explain it to me? – Arnaud ANGIBAUD Sep 17 '19 at 08:57
  • 2
    Post your complete code, the important part where you initialize objects and usage. – Wonka Sep 17 '19 at 08:57
  • Your code and error message are incompatible with each other. Show the code in a state where it produces the error. – blues Sep 17 '19 at 09:00
  • @blues Sorry i mixed up between my tries. But I modifed the code to match the code error – Arnaud ANGIBAUD Sep 17 '19 at 09:03

1 Answers1

1

The problem is that you have overwritten the __init__ method from the parent class. Usually what you is first call the __init__ method from the parent class that can be accessed using the super(). So your code should be something like:

class ExportGUI(Parent_Class):

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

UPDATE:

Now that you've cleared certain details I can augment this answer. Notice that the __init__ call from the ExportGUI is now called with two passed arguments, namely hdf5w and master, the first one is needed to successfully call the __init__ from the parent class. Thus you need to change the code in the definiton of Parent_Class where you're creating an instance of ExportGUI, so that a proper value for hdf5w will be passed in -- my guess would be, you want to pass the value from the parent class:

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

And I can't help but notice, that the arguments passed to Parent_Class.__init__ namely hdf5w and master are not used anywhere. Maybe you want to either save those in variables, for example:

class Parent_Class(GUI):

    def __init__(self,hdf5w,master):
        self.hdf5w = hdf5w
        self.master = master

If those are the same and should be carried across to the ExportGUI they can be simply passed when you're creating an instance in the export function of the Parent_Class. If you don't need them and decide to remove them, make sure to modify the __init__ call of the Parent_Class as well as the super().__init__ call in the ExportGUI.

gstukelj
  • 2,291
  • 1
  • 7
  • 20
  • This won't be enough: not only `Extended_Class` but also `Parent_Class` has to call its inherited `__init__()`. – Schmuddi Sep 17 '19 at 09:12
  • You're right, the __init__() gets overwritten there as well. However, his problem was specific and apparently calling Parent_Class.ohdf5 works as expected. – gstukelj Sep 17 '19 at 09:16
  • @Schmuddi So i modified my code but I got a code error because of `ExportGUI(new_window2) TypeError: __init__() takes exactly 3 arguments (2 given)` what should I fill in? – Arnaud ANGIBAUD Sep 17 '19 at 09:19
  • What error did you get? Did you read about inheritance and how to use super()? – gstukelj Sep 17 '19 at 09:21
  • I got the error code that I just mentionned above. Sorry I didnt see your link to `super` doc. I'll read it and comeback after. – Arnaud ANGIBAUD Sep 17 '19 at 09:23
  • Where is `ExportGUI()` defined? Should it maybe be `self.ExportGUI(new_window2)`? – gstukelj Sep 17 '19 at 09:30
  • That is the problem when you change variables name to make code more cleaner. `ExportGUI` is what I called here `Extended_Class`. – Arnaud ANGIBAUD Sep 17 '19 at 12:03
  • Ok, please update your question. I'll update my answer accordingly as well. – gstukelj Sep 17 '19 at 12:17