从本质上讲,你的问题有一个简单的答案。“如何从对象X获取值?” 对于任何对象,答案都是相同的:你可以通过询问对象X来获得答案。为此,你所需要做的就是获取对该对象的引用,然后直接访问该属性。
在你的情况下,中的代码PageTwo
需要引用,PageOne
以便你可以获取v
变量。
那么,你如何获得参考?代码(从教程复制或从教程复制的stackoverflow答案复制)旨在简化此过程。每个页面都有对控制器的引用,该控制器也具有对每个页面的引用。因此,你可以要求控制器为你提供对页面的引用。
第一步是将引用保存到每个类中的控制器。有趣的是,你已经在中执行了此操作PageOne,但是你应该在所有页面中都执行此操作。确保添加self.controller = controller
每种__init__
方法,如下所示:
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
...
self.controller=controller
...
接下来,我们需要在控制器类中添加一个方法,该方法将返回对该页面的引用。将以下功能添加到SampleApp
:
class SampleApp(tk.Tk):
...
def get_page(self, page_class):
return self.frames[page_class]
...
现在,你可以从任何“页面”中访问任何其他“页面”的对象。例如,PageTwo
你可以像这样访问v变量PageOne:
page1 = self.controller.get_page(PageOne)
page1.v.set("Hello, world")
使用共享数据 更好的解决方案是让你的SampleApp
类创建一组所有页面共享的变量。你可以在该类中创建字典,然后使用控制器授予每个页面访问权限。例如:
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.shared_data = {
"username": tk.StringVar(),
"password": tk.StringVar(),
...
)
然后,可以从任何类中访问如下数据:
entry1 = tk.Entry(self, textvariable=self.controller.shared_data["username"])
...
username = self.controller.shared_data["username"].get()
之所以是更好的解决方案,是因为你的页面不必知道其他页面的实现方式。当页面依赖于另一页面的确切实现时,这称为紧密耦合。如果页面不需要知道其他页面的实现方式,则称为松耦合。
松耦合使你更具灵活性。它们不是将每个页面都紧密地耦合到其他页面,而是都紧密地耦合到一个对象:控制器。只要每个页面只知道控制器,每个页面都可以随时更改,而不会影响程序的其余部分。
当然,如果要更改控制器,则必须更改所有页面,但是如果设计得好,则不太可能出现该控制器,并且在出现时更易于管理。