Python Tkinter - 从另一个类输入.get()

时间:2013-12-21 21:09:25

标签: python tkinter

我最近遇到了一个问题,这个问题困扰着我的tkinter入口.get()函数,我已经把一个示例代码放在一起,所以你可以看到我正在尝试做什么,我有两个类,一个类对于每个窗口。在第一个窗口(主窗口)中我有一个输入框,在第二个窗口中我试图从第一个窗口获取输入框文本。

这是代码:(试图从第二堂课的第一堂课获得入境箱信息)

from Tkinter import *

class window_1(object):

    def __init__(self):
        self.app = Tk()
        self.app.title("Window One")

    def entrybox(self):
        self.ent = Entry(self.app) #This is the text i'm trying to get in 2nd class

    def button(self):
        def ODV(self):
            class window_2(object):
                def __init__(self):
                    self.app2 = Tk()
                    self.app2.title("Window Two")

                def labels(self):
                    self.label_0 = Label(self.app2, text = "Name: ")

                def info(self):
                    self.fetch_name = self.ent.get()#Here is my problem

                def gridder(self):
                    self.label_0.grid(row = 0, column = 0)
                    self.fetch_name.grid(row = 0, column = 1)

            rooter = window_2()
            rooter.labels()
            rooter.info()
            rooter.gridder()

        open_data_viewer = lambda: ODV(self)
        self.but = Button(self.app, text = "Save", command = open_data_viewer)

    def packer(self):
        self.ent.pack(anchor = W)
        self.but.pack(anchor = W)

    def App_Runner(self):
        self.app.mainloop()

    root = window_1()
    root.entrybox()
    root.button()
    root.packer()
    root.App_Runner()

1 个答案:

答案 0 :(得分:1)

您的第一个问题是您正在创建多个Tk的实例。你不能这样做,tkinter不是那样设计的。如果您想要多个窗口,请创建Toplevel的实例。 tkinter程序应始终只有Tk的一个实例,只有一个mainloop的调用,并且在调用mainloop之后应该几乎没有代码。

其次,在函数中嵌入类的定义绝对没有价值。移出它,它将使您的代码更容易理解,更容易编写和维护。

第三,对于一个对象访问另一个对象上的方法的实例,第一个对象需要知道第二个对象或需要知道中央“控制器”对象。这不是一个tkinter问题,在编写OO代码时需要考虑这一点。

从实际角度来看,在创建第二个对象时,需要将引用传递给条目窗口小部件或包含条目窗口小部件的对象。例如:

class window_2(object):
    def __init__(self, other):
        ...
        self.other = other
        ...
    def info(self):
        self.fetch_name = self.other.ent.get()
... 
rooter = window_2(self) # pass "self" to the new object

这会在两个对象之间产生紧耦合 - 第二个对象知道第一个对象的内部工作原理。这不是很好的设计,但对于非常非常简单的程序来说,它并不是那么糟糕。问题是这样的:如果你改变第一个小部件的布局,也许将“self.ent”重命名为“self.some_other_frame.ent”,你也必须修改另一个小部件。

更好的解决方案是在您的第一个类中定义一个获取其自身价值的函数。当然,ent用于此目的,但同样,这是一种紧密耦合。最好有一个辅助功能:

class window_1(object):
    ...
    def get_string(self):
        return self.ent.get()

class window_2(object):
    def info(self):
        self.fetch_name = self.other.get_string()

这仍然有一个松散耦合,但更容易管理,因为耦合不依赖于特定的内部布局和第一个窗口的名称。只要您继续提供执行其他类所期望的get_string方法,您就可以随意更改小部件。你的第一堂课是为第二课提供合同:承诺无论窗口如何随时间变化,它都承诺提供这个界面。