Reputation: 9521
I am trying to work out an MVC structure for a tkinter program.
I have a view class with an event binding for mouse click as follows
class View():
def __init__(self, root)
self.canvas = Canvas(root)
self.canvas.pack()
self.canvas.bind("<Button-1>", self.select)
def select(self):
# do some thing
I have another class 'Controller'
class Controller:
def __init__(self, root):
self.model = model.Model()
self.view = view.View(self.model)
#root.bind_class("Canvas", "<Button-1>", self.view.select)
I need to move the event binding from view to the controller. How do I bind the canvas widget created in view class from the controller class?
I have worked out a temporary solution in the controller class by binding the entire Canvas widget to the event using root.bind_class("Canvas", "<Button-1>", self.view.select)
.
Currently there is only one canvas widget in my GUI and this works fine. However adding more canvases later on may pose problem.
Upvotes: 0
Views: 2196
Reputation: 9521
After trying hard out to implement MVC with tkinter, I came across an article on why MVC may not be the best bet for GUI programming.
"However, the traditional MVC scope falls short when it comes to the control of GUI >elements (widgets). MVC does not handle the complexities of data management, event >management, and application flows. As an adaptation of the MVC triad, the HMVC -- >Hierarchical-Model-View-Controller -- paradigm seeks to redress some of the above-mentioned >issues."
Jason Cai, Ranjit Kapila, and Gaurav Pal (July 2000). "HMVC: The layered pattern for >developing strong client tiers". JavaWorld Magazine.
Upvotes: 0
Reputation: 20679
With the MVC pattern, the controller should respond to user events caused by the interaction with the view. Thus, if you want to follow that approach, then select
should be in the controller and the view only needs to know what action of the controller has to respond:
class View():
def __init__(self, master, controller):
self.canvas = Canvas(root)
self.canvas.pack()
self.canvas.bind("<Button-1>", controller.select)
class Controller():
def __init__(self, master):
self.model = model.Model()
self.view = view.View(master, self)
def select(self, event):
canvas = event.widget
# ...
You can also bind <Button-1>
in the controller after creating the View object, but then you are coupling the code of the controller with the view (Controller should know that View has always a self.canvas
attribute).
Upvotes: 2