English 中文(简体)
如何在 TkInter 创建儿童窗口和与父母沟通
原标题:How to create child window and communicate with parent in TkInter

我在使用 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)

点击 < 坚固> New... 按钮时,将显示一个 Create Company 对话框,使用户能够填入公司细节,并单击创建或取消。 这里显示打开部分 :

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

on New () < () _BAR_BAR__BAR_BAR__BAR_BAR__BAR_BAR__BAR__BAR__BAR_BAR__BAR_BAR__BAR_BAR__BAR_BAR_BAR_BAR_BAR__BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_BAR_#() <() <) <() <)

我曾尝试过在线教程/ 参考, 但我发现要么过于简单化, 要么专注于诸如 tkMessageBox.showinfo > () 之类的事情, 这并不是我想要的。

最佳回答

至少有几种方法可以解决您的问题。 您的对话框可以直接将信息发送到主应用程序, 或者您的对话框可以生成一个事件, 告诉主要应用程序, 数据真的要从对话框中提取。 如果对话框只是改变某东西的外观( 例如, 字体对话框), 我通常会生成一个事件。 如果对话框创建或删除数据, 我通常会将信息反馈到应用程序中 。

我通常有一个应用程序对象, 作为整个 GUI 的控制器。 通常这是主窗口的同一类别, 或者可能是单独的类别, 或者甚至被定义为混音。 此应用程序对象有对话框可以调用的方法将数据输入到应用程序中 。

例如:

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

创建对话框时,您会通过应用程序对象的引用。然后,该对话框可以调用此对象上的具体方法将数据发送到应用程序中。

如果您没有进入整个模型/视图/控制器, 您可以在函数而不是对象中同样容易通过, 有效地告诉对话框“ 当您想要给我数据时, 调用此函数 ” 。

问题回答

在我的一个项目中,我试图在我的根窗口(自己)的 孩子tk.Toplevel窗口(Child1)中检查,如果用户在根窗口内创建了tk.Toplevel窗口(Child2),以及这个窗口(Child2)是否出现在用户屏幕上。

如果不是这样的话, 新的 tk.Toplevel 窗口应该由根窗口的儿童窗口( child1) 而不是根窗口本身创建。 如果它已经由根窗口创建,并且目前存在于用户屏幕上, 它应该被焦点( ) 而不是被“ child1” 重新激活 。

根窗口被包裹在名为 App () 的类中, 两个“ 孩子” 的窗口都是用根类 App () 内的方法创建的 。

如果对方法的争论是真实的,我不得不以安静的方式初始化“ child2 ” 。 我想这是纠缠的错误。 问题出现在 Windows 7 64 位上, 如果问题重大的话 。

我试过这个(例如):

import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        top = self.winfo_toplevel()
        self.menuBar = tk.Menu(top)
        top[ menu ] = self.menuBar
        self.menuBar.add_command(label= Child1 , command=self.__create_child1)
        self.menuBar.add_command(label= Child2 , command=lambda: self.__create_child2(True))
        self.TestLabel = ttk.Label(self, text= Use the buttons from the toplevel menu. )
        self.TestLabel.pack()
        self.__create_child2(False)

    def __create_child1(self):
        self.Child1Window = tk.Toplevel(master=self, width=100, height=100)
        self.Child1WindowButton = ttk.Button(self.Child1Window, text= Focus Child2 window else create Child2 window , command=self.CheckForChild2)
        self.Child1WindowButton.pack()

    def __create_child2(self, givenarg):
        self.Child2Window = tk.Toplevel(master=self, width=100, height=100)
        if givenarg == False:
            self.Child2Window.withdraw()
            # Init some vars or widgets
            self.Child2Window = None
        else:
            self.Child2Window.TestLabel = ttk.Label(self.Child2Window, text= This is Child 2 )
            self.Child2Window.TestLabel.pack()

    def CheckForChild2(self):
        if self.Child2Window:
            if self.Child2Window.winfo_exists():
                self.Child2Window.focus()
            else:
                self.__create_child2(True)
        else:
            self.__create_child2(True)

if __name__ ==  __main__ :
    App().mainloop()

Here comes the problem: I wasn t able to check if "child2" is already present. Got error: _tkinter.TclError: bad window path name

解决方案 :

获得正确的窗口路径名称的唯一办法是, 而不是直接在“ child2” 窗口上调用 winfo_ expences () 方法, 而不是调用“ child1” 窗口的主控器, 并添加属性, 加上您想要使用的主窗口的属性 。

示例(方法校验Child2的编辑):

    def CheckForChild2(self):
        if self.Child2Window:
            if self.Child1Window.master.Child2Window.winfo_exists():
                self.Child1Window.master.Child2Window.focus()
            else:
                self.__create_child2(True)
        else:
            self.__create_child2(True)




相关问题
Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

An enterprise scheduler for python (like quartz)

I am looking for an enterprise tasks scheduler for python, like quartz is for Java. Requirements: Persistent: if the process restarts or the machine restarts, then all the jobs must stay there and ...

How to remove unique, then duplicate dictionaries in a list?

Given the following list that contains some duplicate and some unique dictionaries, what is the best method to remove unique dictionaries first, then reduce the duplicate dictionaries to single ...

What is suggested seed value to use with random.seed()?

Simple enough question: I m using python random module to generate random integers. I want to know what is the suggested value to use with the random.seed() function? Currently I am letting this ...

How can I make the PyDev editor selectively ignore errors?

I m using PyDev under Eclipse to write some Jython code. I ve got numerous instances where I need to do something like this: import com.work.project.component.client.Interface.ISubInterface as ...

How do I profile `paster serve` s startup time?

Python s paster serve app.ini is taking longer than I would like to be ready for the first request. I know how to profile requests with middleware, but how do I profile the initialization time? I ...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

Converting Dictionary to List? [duplicate]

I m trying to convert a Python dictionary into a Python list, in order to perform some calculations. #My dictionary dict = {} dict[ Capital ]="London" dict[ Food ]="Fish&Chips" dict[ 2012 ]="...

热门标签