Tkinter父对子数据交换

时间:2015-04-06 07:50:59

标签: python-2.7 tkinter

我希望这不是一个重复的问题,因为提出了一个解决方案here,我很难让它发挥作用。 (或者我可以在同一个讨论中发布这个)

目标:

在主窗口中,用户输入一些数据,如果单击,则会出现一个带有父数据的新子窗口,最终对它们进行操作,然后将结果发送回父窗口小部件。

enter image description here

使用的代码:

from Tkinter import *

class trackApp(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)

        self.mainVar1 = IntVar()
        self.mainVar2 = IntVar()

        self.mainVar1.set(100)
        self.mainVar2.set(100)
        self.master = master
        self.master.geometry('400x200+100+200')
        self.master.title('MAIN WINDOW')

        self.label1=Label(self.master,text='Variable1 : ').grid(row=1,column=1)
        self.mainEntry1=Entry(self.master,textvariable=self.mainVar1).grid(row=1,column=2)

        self.label2=Label(self.master,text='Variable2 : ').grid(row=2,column=1)
        self.mainEntry2=Entry(self.master,textvariable=self.mainVar2).grid(row=2,column=2)

        self.button1=Button(self.master,text='Child',command=self.dialogWindow).grid(row=7,column=2)


    def new_data(self, data):
        self.mainEntry1.delete(0,END)
        self.mainEntry1.insert(0,self.data['var1'])
        self.mainEntry2.delete(0,END)
        self.mainEntry2.insert(0,self.data['var2'])


    def dialogWindow(self):
        # Build a list from control variables used in the main window text entry boxes
        mainList = [self.mainVar1.get(),self.mainVar2.get()]

        top=Toplevel(self.master)
        childDialog=childWindow(top,mainList, self.master)


class childWindow(Frame):

    # Pass data (list) to the child
    def __init__(self, master, list, app):

        self.list = list

        self.app = app
        self.master = master
        self.master.geometry('300x100+150+250')
        self.master.title('CHILD WINDOW')

        # Define control variabels to be used with child window text entry widgets
        self.childvar1 = IntVar()
        self.childvar2 = IntVar()

        # Fill child window text entry widgets with inf. from parent window
        self.childvar1.set(list[0])
        self.childvar2.set(list[1])

        # Text entry widgets
        self.label1=Label(self.master,text='Enter New value 1').grid(row=0,column=1)
        self.childEntry1=Entry(self.master,textvariable=self.childvar1).grid(row=0,column=2)

        self.label2=Label(self.master,text='Enter New value 2').grid(row=1,column=1)
        self.childEntry2=Entry(self.master,textvariable=self.childvar2).grid(row=1,column=2)

        self.button1=Button(self.master,text='OK',command=self.childDestroy).grid(row=3,column=1)


    def childDestroy(self):

        self.data = {}
        self.data['var1'] = self.childvar1.get()
        self.data['var2'] = self.childvar2.get()

        trackApp.app.new_data(self, self.data)  # <<<<<<<<< How to call the parent new_data method

        self.master.destroy()


def main():
    root = Tk()
    app = trackApp(root)
    root.mainloop()

if __name__ == "__main__":
    main()

问题:

如何从孩子那里引用父方法( new_data )?

错误:

/usr/bin/python2.7 /<path>/child-dialog.py
Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__
    return self.func(*args)
  File "/<path>/child-dialog.py", line 77, in childDestroy
    trackApp.app.new_data(self, self.data)  # <<<<<<<<< How to call the parent new_data method
AttributeError: class trackApp has no attribute 'app'

2 个答案:

答案 0 :(得分:1)

错误消息告诉您问题的确切原因:它表示trackApp没有属性'app',并且查看该类的定义时,我看不到属性'app'

要让您的子窗口知道它的父级,您需要为其提供对父级的引用。因此,在创建窗口时,您将传入引用,并在子窗口中使用引用。

看起来你正试图这样做,但是你输入了错误的值,然后你没有使用该值。您需要修改代码,如下所示:

class trackApp(Frame):
    ...
def dialogWindow(self):
    ...
    childDialog=childWindow(top,mainList, self)

class childWindow(Frame):
    def childDestroy(self):
        ...
        self.app.new_data(self, self.data) 
        ... 

答案 1 :(得分:-1)

感谢Bryan的回答。以下是我所做的更改:

将父(self)传递给子窗口

def dialogWindow(self):
    childDialog=childWindow(top,mainList, self)

使用父实例(self)调用父方法

def childDestroy(self)    
    self.app.new_data(self.data) 

以及以下更新主窗口小部件:

def new_data(self, data):
    self.mainVar1.set(data['var1'])
    self.mainVar2.set(data['var2'])

感谢您的帮助。