简体   繁体   English

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

[英]I can't pass parent variables through Tkinter in Python 2.7

First of All, I have to say that I am a beginner in Python, so my code might appears redundant or muddled. 首先,我必须说我是Python的初学者,所以我的代码可能显得多余或混乱。 I made this code which consists of two classes that are both tkinter frame. 我编写了由两个都属于tkinter框架的类组成的代码。 The class ExportGUI inherits from Hdf5GUI and is called by the function export . ExportGUI继承自Hdf5GUI ,并由函数export调用。 The thing is I am trying to access the parent variable datasetsfilter through a child function but it doesnt work : 事情是我试图通过一个datasetsfilter访问父变量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)

So until now my code perfectly works but I had to complete my program with some other functions that I call in ExportGUI . 所以直到现在我的代码都可以正常工作,但是我必须用ExportGUI调用的其他一些函数来完成我的程序。 For example export_filter . 例如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 ). 既不ohdf5datatsetsfilter通过已知ExportGUI (我有相同的错误self.datatsetsfilter )。 Considering this code didnt work I tried to use the super function. 考虑到此代码不起作用,我尝试使用super功能。 I created a function get_datasetsfilter in Hdf5GUI : 我在Hdf5GUI创建了一个函数get_datasetsfilter

 def get_datasetsfilter(self):
        return self.datasetsfilter

and then called it in ExportGUI (I added __metaclass__ = type to fix type prblm in 2.7) : 然后在ExportGUI调用它(我在2.7中添加了__metaclass__ = type来修复类型prblm):

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. 我承认我看到了Super许多其他示例,但它们似乎都用于__init__方法。 However, it still doesnt work. 但是,它仍然不起作用。 I am now wondering if the error results from my bad comprehension of inheritance or tkinter . 我现在想知道错误是否是由于我对继承或tkinter理解不正确导致的。

The problem is that you have overwritten the __init__ method from the parent class. 问题是您已经从父类覆盖了__init__方法。 Usually what you is first call the __init__ method from the parent class that can be accessed using the super() . 通常,您首先要从可以使用super()访问的父类中调用__init__方法。 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. 请注意,现在已使用两个传递的参数(即hdf5wmaster调用了ExportGUI__init__调用,需要第一个参数才能成功从父类调用__init__ 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: 因此,你需要改变的definiton代码Parent_Class ,你正在创建的实例ExportGUI ,这样对于hdf5w正确的值将被传递-我的猜测是,你想从父类传递价值:

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. 而且我不禁注意到,传递给Parent_Class.__init__的参数hdf5wmaster在任何地方都没有使用。 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 . 如果这些是相同的,应在整个抬到ExportGUI他们可以当你创建的一个实例可以简单地通过export的功能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 . 如果您不需要它们,并决定将其删除,请确保修改了__init__的呼叫Parent_Class还有super().__init__呼叫ExportGUI

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM