如何在 TkInter 中创建子窗口并与父窗口通信 [英] How to create child window and communicate with parent in TkInter

查看:78
本文介绍了如何在 TkInter 中创建子窗口并与父窗口通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 TkInter 创建一些对话框,并且需要能够在单击父级中的按钮时打开子子窗口(模态或非模态).然后子窗口将允许创建数据记录,并且需要将此数据(记录或操作被取消)传送回父窗口.到目前为止,我有:

import sel_company_dlg从 Tkinter 导入 Tk定义主():根 = Tk()myCmp = sel_company_dlg.SelCompanyDlg(root)root.mainloop()如果 __name__ == '__main__':主要的()

这将调用允许用户选择公司的顶级对话框.公司选择对话框如下所示:

class SelCompanyDlg(Frame):def __init__(self, parent):Frame.__init__(self, parent)self.parent_ = 父母self.frame_ = Frame( self.parent_ )//.. 更多初始化的东西 ..self.btNew_ = Button( self.frame_, text="New ...", command=self.onNew )def onNew(self):根 = 顶层()myCmp = company_dlg.CompanyDlg(root)

单击新建... 按钮后,将显示创建公司对话框,允许用户填写公司详细信息并单击创建或取消.这是它的开场白:

class CompanyDlg(Frame):def __init__(self, parent):Frame.__init__(self, parent)//等等.

我正在努力寻找在 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):# 将数据发送给父级self.app.new_data(...来自这个对话框的数据...)类 MainApplication(tk.Tk):...def on_show_dialog(self):对话框 = ChildDialog(self)对话框显示()def new_data(self, data):... 处理从对话框传入的数据 ...

创建对话框时,您传入对应用程序对象的引用.对话框然后知道调用此对象的特定方法以将数据发送回应用程序.

如果你不了解整个模型/视图/控制器,你可以很容易地传入一个函数而不是一个对象,有效地告诉对话框当你想给我数据时调用这个函数".

I'm creating some dialogs using TkInter and need to be able to open a child sub-window (modal or modeless) on clicking a button in the parent. The child would then allow a data record to be created and this data (either the record or if the operation was cancelled) needs to be communicated back to the parent window. So far I have:

import sel_company_dlg

from Tkinter import Tk

def main():
    root = Tk()
    myCmp = sel_company_dlg.SelCompanyDlg(root)
    root.mainloop()

if __name__ == '__main__':
    main()

This invokes the top level dialog which allows the user to select a company. The company selection dialog looks like this:

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)

On clicking the New ... button, a Create Company dialog is displayed which allows the user to fill in company details and click on create or cancel. Here's the opening bit of that:

class CompanyDlg(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        // etc.

I'm struggling with the best way of invoking the child dialog in onNew() - what I have works but I'm not convinced it's the best approach and also, I can't see how to communicate the details to and from the child dialog.

I've tried looking at online tutorials / references but what I've found is either too simplistic or focuses on things like tkMessageBox.showinfo() which iss not what I want.

解决方案

There are at least a couple ways to solve your problem. Either your dialog can directly send information to the main application, or your dialog can generate an event that tells the main application that data is really to be pulled from the dialog. If the dialog simply changes the appearance of something (for example, a font dialog) I usually generate an event. If the dialog creates or deletes data I typically have it push information back to the application.

I typically have an application object that acts as the controller for the GUI as a whole. Often this is the same class as the main window, or it can be a separate class or even defined as a mixin. This application object has methods that dialogs can call to feed data to the application.

For example:

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 ...

When creating the dialog, you pass in a reference to the application object. The dialog then knows to call a specific method on this object to send data back to the application.

If you're not into the whole model/view/controller thing you can just as easily pass in a function rather than an object, effectively telling the dialog "call this function when you want to give me data".

这篇关于如何在 TkInter 中创建子窗口并与父窗口通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆