我正在使用TkInter创建一些对话框,并且需要能够在单击父级中的按钮时打开子子窗口(模态或无模式).然后,子项将允许创建数据记录,并且需要将此数据(记录或操作被取消)传送回父窗口.到目前为止,我有:
import sel_company_dlg from Tkinter import Tk def main(): root = Tk() myCmp = sel_company_dlg.SelCompanyDlg(root) root.mainloop() if __name__ == '__main__': main()
这将调用顶级对话框,允许用户选择公司.公司选择对话框如下所示:
class SelCompanyDlg(Frame): def __init__(self,parent): Frame.__init__(self,parent) self.parent_ = parent self.frame_ = Frame( self.parent_ ) // .. more init stuff .. self.btNew_ = Button( self.frame_,text="New ...",command=self.onNew ) def onNew(self): root = Toplevel() myCmp = company_dlg.CompanyDlg(root)
单击“新建…”按钮后,将显示“创建公司”对话框,允许用户填写公司详细信息并单击“创建”或“取消”.这是开头的一点:
class CompanyDlg(Frame): def __init__(self,parent) // etc.
我正忙着在onNew()中调用子对话框的最佳方式 – 我有什么工作,但我不相信这是最好的方法,而且,我也看不出如何与孩子沟通细节对话.
我已经尝试过查看在线教程/参考资料,但我发现它要么过于简单化,要么专注于像tkMessageBox.showinfo()这样的东西,这不是我想要的.
解决方法
至少有几种方法可以解决您的问题.您的对话框可以直接将信息发送到主应用程序,或者您的对话框可以生成一个事件,告诉主应用程序确实要从对话框中提取数据.如果对话框只是改变了某些东西的外观(例如,字体对话框),我通常会生成一个事件.如果对话框创建或删除数据,我通常会将信息推送回应用程序.
我通常有一个应用程序对象作为整体GUI的控制器.通常这是与主窗口相同的类,或者它可以是单独的类,甚至可以定义为mixin.此应用程序对象具有对话框可以调用以将数据提供给应用程序的方法.
例如:
class ChildDialog(tk.Toplevel): def __init__(self,parent,app,...) self.app = app ... self.ok_button = tk.Button(parent,...,command=self.on_ok) ... def on_ok(self): # send the data to the parent self.app.new_data(... data from this dialog ...) class MainApplication(tk.Tk): ... def on_show_dialog(self): dialog = ChildDialog(self) dialog.show() def new_data(self,data): ... process data that was passed in from a dialog ...
创建对话框时,传入对应用程序对象的引用.然后,对话框知道在此对象上调用特定方法以将数据发送回应用程序.
如果你没有进入整个模型/视图/控制器的东西,你可以轻松地传入一个函数而不是一个对象,有效地告诉对话框“当你想给我数据时调用这个函数”.