如何将模型动作传递给 Tkinter MVC 中的查看按钮?
Posted
技术标签:
【中文标题】如何将模型动作传递给 Tkinter MVC 中的查看按钮?【英文标题】:How to pass Model action to View button in Tkinter MVC? 【发布时间】:2018-02-21 14:31:54 【问题描述】:我正在尝试使用 Tkinter 将 GUI 开发为 MVC 模式,但这种方式对我来说是新的。我在网上看到了很多例子,但我仍然更喜欢了解它是如何工作的。这就是为什么我只是编写一个简单的应用程序来获取它。
开始,我只有树文件 controller.py、view.py 和 model.py。第一个是 View 和 Model 之间的连接器,但最后一个从未相互链接。模型只包含方法/函数;和查看图形界面,我的意思是小部件。
问题是,如果 View 类(view.py)有一个没有命令的按钮,并且这个按钮应该执行的操作是在 Models 类(model.py)中,我必须为 Controller 类(controller.py)写什么? py) 获取此操作并将其分配给按钮?
view.py 文件:
#!/usr/bin/python
# -*- coding:UTF-8 -*-
from Tkinter import*
class View():
def __init__(self, master):
self.master = master
master.title("MAIN GUI")
master.geometry("400x200")
l = Label(master, text="TITLE SCREEN")
l.pack()
b = Button(master, text='Hello')
b.pack()
model.py 文件:
#!/usr/bin/python
# -*- coding:UTF-8 -*-
from Tkinter import*
from tkMessageBox import*
class Model():
def __init__(self):
pass
#Greeting() #I don't know if this should be here.
def Greeting(self):
print "Hello world"
def Alert(self):
showinfo ('msg', "Hello world")
controller.py:
#!/usr/bin/python
# -*- coding:UTF-8 -*-
from view import*
from model import*
class Controller():
def __init__(self, master):
View(root)
Model()
View.b.config(command=Model.Greeting)
#View.b.config(command=self.Action)
def Action(self):
Model.Greeting()
if __name__ == "__main__":
root = Tk()
View(root)
root.mainloop()
【问题讨论】:
你可以使用signal/slot
的想法(例如PyPubSub
或PyDispatcher
或blinker
)。您不妨看看 Ninad Sathaye 的《学习 Python 应用程序开发》一书的第 10 章。第 10 章使用tkinter
解释并实现了一种类型的 MVC。对于 MVC 的许多变体,您不妨参考 Stefano Borini 的书《理解模型-视图-控制器》。
【参考方案1】:
您可以在控制器 init() 函数中使用它:
self.view.b.bind("<Button>",self.action)
这样您就不必在视图中使用命令。
我仍在试图弄清楚如何为菜单按钮执行此操作...因此,如果它对您来说是新的(就像对我一样),这可能会有点困难。
编辑: 根据要求,一个小样本:
import tkinter as tk
# Data stuff
class Model():
def __init__(self):
pass
# GUI
class View():
def __init__(self, master):
self.master = master
self.b = tk.Button(self.master, text="quit")
self.b.pack()
# Logic of the app
class Controller():
def __init__(self):
self.root = tk.Tk()
self.model=Model()
self.view=View(self.root)
self.view.b.bind("<Button>",self.action)
self.run()
def run(self):
self.root.mainloop()
def action(self,event):
self.root.destroy()
if __name__ == '__main__':
c = Controller()
【讨论】:
在这种情况下,一个最小的工作示例会有所帮助。 已经提供了一个例子。【参考方案2】:如果按钮没有命令,那么什么都不会发生。 它需要有一个命令,调用控制器的功能。
然后,控制器将通过与模型通信或触发另一个视图来执行此命令。
由于按钮要调用控制器的功能,它需要意识到这一点。
假设您将它作为参数传递,并且您希望按钮触发controller.Action
,controller
是Controller
的(?)实例。
您的视图应如下所示:
class View():
def __init__(self, master, controller):
self.master = master
self.controller = controller
b = Button(master, text='Hello', command=self.controller.Action())
b.pack()
然后,点击按钮将调用Action
。
【讨论】:
以上是关于如何将模型动作传递给 Tkinter MVC 中的查看按钮?的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET MVC我想重定向到另一个将我的模型传递给它的动作,以获得正确的URL
如何序列化模型,将其传递给 ajax 请求中的 MVC 控制器