Python 2.7 - 如何在Tkinter GUI中使用Observer,在帧之间切换?

时间:2016-08-16 14:55:20

标签: python model-view-controller tkinter event-handling observer-pattern

我目前正在开发一个基于线程How to get variable data from a class的GUI。由于将要处理大量数据,我想使用Model-Class,它通过Observer得到它的更新。

目前,第一页SetEnv TYPO3_CONTEXT Development 的更改已通过ttk.Combobox注册,已移至<<ComboboxSelect>>的变量self.shared_data并传递给Controller }。这样,就不会使用Oberserver / Observable逻辑。相反,只要用户在GUI中执行相应的操作,就会更改Model中的数据。

但是,我不想使用像Model这样的绑定来更改<<ComboboxSelect>>中的相应数据,而是使用Observer / Observable逻辑来检测,即条目{{ {}更改了Model内的字典"Inputformat"中的1}},后者又刷新了self.shared_data中的数据,即Controller,其中Model的实际状态1}}已保存。

简而言之,我希望通过使用Observer实现以下功能:

用户选择self.model_data - >中的“条目01”。 ttk.Combobox中的self.shared_data [“Inputformat”]现在填充“Entry 01” - &gt; Observer / Observable逻辑检测到这一点 - &gt; ttk.Combobox中的相应变量正在改变。

为了让你有一些工作,这里是代码。

Controller

1 个答案:

答案 0 :(得分:2)

由于我无法实现观察者来观看像ttk.Combobox这样的小部件,我决定创建一个变通方法。以下是我采取的步骤,以便从Bryan Oakleys实例(链接在问题中)实现MVC架构,每当用户在视图(GUI)中执行操作时,都会通过控制器类刷新其模型类。

第1步:添加模型类

首先,为了使用MVC架构,我们必须将代码分成模型,视图和控件。在此示例中,模型为class Model:,控件为class PageControl(tk.Tk):,视图为class StartPage(tk.Frame)PageOne(tk.Frame)PageTwo(tk.Frame)

第2步:设置模型类

现在我们必须决定我们想要在模型类中使用哪些变量。在这个例子中,我们有目录和键(组合框的状态),我们想要保存在词典中。在将它们设置为空之后,我们所要做的就是为每个变量添加setter和getter,这样我们就可以刷新模型中的数据并根据需要检索一些数据。另外,如果我们愿意的话,我们可以为每个变量实现delet方法。

第3步:将推拉方法添加到控件类

现在有一个模型类,我们可以通过e来引用它。 G。 self.model = Model()(控件)中的PageControl(tk.Tk)。现在我们有了基本工具来通过e在Model中设置数据。 G。 self.model.set_keys(self.shared_keys)并从Model获取数据。既然我们希望我们的控件类能够做到这一点,我们需要一些可以实现这一目标的方法。因此,我们将推送和拉取方法添加到PageControl(例如def push_key(self)),然后可以通过控制器从视图(StartPage,PageOne,PageTwo)中进行修改。

第4步:将小部件添加到视图类

现在我们必须决定哪些小部件应该在哪个页面上以及您希望他们做什么。在这个例子中,有一些导航按钮,为了完成任务,可以忽略两个组合框和一个打开文件对话框的按钮。

在这里,我们希望组合框在更改时刷新其状态,并通过控制器将新状态发送到模型。而Open的{​​{1}}按钮将打开文件对话框,然后用户选择他/她想要打开的文件。然后我们从这次交互中获得的目录将通过控制器发送到模型。

第5步:将所有功能纳入控制器类

由于存在控制器变量,我们可以使用它来引用控制器类中的方法。这样,我们可以将所有方法从页面外包到控制器中,并通过self.controller.function_of_controller_class引用它们。但是我们必须要知道,通过PageOne绑定到命令的方法不能返回任何值,但是在程序启动时也不会调用它们。所以记住这一点。

第6步:设置绑定和包装

我们必须为我们的组合框设置lambda:。由于控制器已经设置为存储数据并且组合框具有文本变量,我们可以使用它来通过.bind()收集有关组合框状态的信息。我们所要做的就是设置一个被调用的包装器,只要combobox.bind(<<ComboboxSelect>>)抛出一个事件。

结束语

现在我们有了一个基于Bryan Oakleys“如何从类中获取可变数据”的示例的程序,该程序使用模型,只要用户在视图中执行相应的操作,该模型就会通过控制器进行更新。不幸的是,它没有像第一个预期的那样使用Observer类,但是当我找到一个令人满意的解决方案时,我会继续研究并更新它。