Thursday, March 24, 2011

Model view controller

I have a tree control in my GUI (with naturally lots of GUI/platform specific functions to handle the nodes).
I have a data model with its own complex set of nodes, children, properties etc..
I want the tree to display a representation of the model, be able to send messages to the nodes inside the model and be told to redraw itself when the model changes.

But I don't want the GUI code to need to know the details of the model's data types and I don't want to pollute the model by linking it to the GUI classes.

I can't get my head around how the controller is supposed to do this and what functions it should provide?

(this is in C++ but that shouldn't matter)

From stackoverflow
  • Qt provides a group of classes for model-view programming. You can hook a tree view to a filesystem model, for example, and neither directly know anything about each other (except a pointer to the model in the view).

  • Your requirements are:

    • Tree displays representation of model
    • Nodes in tree can send messages to nodes inside model
    • Tree redraws itself based on model changes

    I don't know exactly what kind of data you're working with here, but a hierarchical model is a fairly simple thing. I'll take it as a given you know how to iterate hierarchical data and populate a tree view.

    Your controller should have member function(s) for sending messages to the model. The parameters should be a model element and the message you want to send. This way, the UI is completely unaware of how the message gets to the element, but can get the messages through.

    The last requirement is more tricky, and depends on a few things (e.g., the lifetime of the controller, application architecture, etc.) I'm going to assume the controller lives as long as the tree view does. If that's the case, then your controller should provide a way to set a callback on model changes. Then, when the controller changes the model, it can callback to the UI without being aware of the UI.

  • You need a controller that sits outside the display widget but has the state of the tree (in MFc there are CTreeView/CTreeCtrl classes - there is a similiar separation in Qt) the tree controller handles all the data storage and calls redraws on the tree widget.
    Changes in the tree widget get sent to the tree controller - so this controller needs to know about the gui functions.

    The model will need set/get functions for all the relevant parameters for the nodes. But these can return simple types so aren't dependent on the gui.

    Updating the view form the model requires sending a message, if you don't want the model to know about your gui messaging the best you can do is register a callback function (a void pointer to a function) from the tree controller - and call this to do an update. This update function can then query the model for the changes.

  • i think your troubles start with an unfortunate choice of words. the 'control' thingies doesn't have anything to do with the 'controller' in MVC. that's why some GUI libraries use other names (widgets is a common one).

    your 'tree control' is the view, not the controller. it should be tied to the GUI, both for display, and to get GUI events and turn them into 'tree events'.

    the controller gets those 'tree events' and does the necessary modifications to the model. that's where you couple the 'action' with the 'response'.

  • GUI "controls" don't quite fit neatly into a model-view-controller pattern because they typically have their own internal model rather than accepting a reference to one. If the control is structured that way, you'll need an adapter class that "data-binds" the control's internal model to the underlying data model.

    This can accomplish something similar to what model-view-controller would, except that the adapter class plays the role both of a view hookup component (updating the GUI from the data model) and a controller (interpreting GUI events into model actions).

  • First Solution: You can implement a "Subject observer" pattern between model and view, with model as the subject and view as the observer. Whenever there is a change in the state of model, it can fire a event to all the observers those are registered, they can update themselves.

    Second Solution: Introduce a controller, which registers with model as observer. Upon receiving a event for update from Model, it can update the view. Even you can decouple view from controller using one more subject observer pattern between controller and view

    Third Solution: Use MVP pattern. Model view Presenter. This pattern used whenever there is no much computation in controller i.e., job of the controller is just to update its corresponding view. Here controller becomes Presenter.

0 comments:

Post a Comment