Home > Qt > Using MVC Design Pattern and Qt Animation Framework

Using MVC Design Pattern and Qt Animation Framework

We have been studying Qt and decided to develop a small chat client project for Maemo. One of the mandatory requirements was the Qt Animation Framework usage. Just for test, or to learn, we designed our application as a big state machine.

Another design decision was to use MVC. But, how integrate model-view-controller and state machine? Well, as you know, views should handle all canvas and animations (if exist). Given this scenario, we splitted states into two types: macro-states and sub-states. Macro-states are the controllers and sub-states are contained by views. Views are responsible by their sub-states processing. Each view have a state called “doneState” which is used to inform respective controller that view is ok to be deleted.

The picture below tries to make it more clear to understand:

abil-statemachine

The transitions inside views are not early defined. If a view has an animation, it is probably that will exist a transition from “static state” to “animation state” inside view state.

Today, Abil (this is the name for the project), has a splash screen, login screen and buddy list screen. The picture above just shows the interaction between splash and login but all components have the same composition: a controller which contains a view. The controller itself is a state and the view has sub-states for static and animation.

The state machine is used to control the screen transitions and to de/allocate controllers. Transitions from splash to login, from login to buddy list screens were defined. But, how implement these transitions without instatiate each controller?

We used Qt Meta Objects to do this job. See code snipped below:

<code>

QtStateMachine machine;
QtFinalState *doneState = new QtFinalState(machine.rootState());
AbilState mainState(MainCtrl::staticMetaObject, &scene, machine.rootState());
AbilState splashState(SplashCtrl::staticMetaObject, &scene, &mainState);
AbilState loginState(LoginCtrl::staticMetaObject, &scene, &mainState);
AbilState buddyState(BuddyCtrl::staticMetaObject, &scene, &mainState);

splashState.addFinishedTransition(&loginState);
loginState.addFinishedTransition(&buddyState);
buddyState.addFinishedTransition(&loginState);

mainState.setInitialAbilState(&splashState);
mainState.addFinishedTransition(doneState);
QObject::connect(&machine, SIGNAL(finished()), QApplication::instance(), SLOT(quit()));

machine.setInitialState(&mainState);
machine.start();QtStateMachine machine;
QtFinalState *doneState = new QtFinalState(machine.rootState());
AbilState mainState(MainCtrl::staticMetaObject, &scene, machine.rootState());
AbilState splashState(SplashCtrl::staticMetaObject, &scene, &mainState);
AbilState loginState(LoginCtrl::staticMetaObject, &scene, &mainState);
AbilState buddyState(BuddyCtrl::staticMetaObject, &scene, &mainState);

splashState.addFinishedTransition(&loginState);
loginState.addFinishedTransition(&buddyState);
buddyState.addFinishedTransition(&loginState);

mainState.setInitialAbilState(&splashState);
mainState.addFinishedTransition(doneState);
QObject::connect(&machine, SIGNAL(finished()), QApplication::instance(), SLOT(quit()));

machine.setInitialState(&mainState);
machine.start();

</code>

Controllers are not instantiated until the last moment. :) But, we are able to add transitions for macro-states. I’ll explain better this solution in another post.

briglia Qt

  1. Kenneth Christiansen
    May 21st, 2009 at 17:29 | #1

    So are you using TelepathyQt4? if not you should be :-) Something makes me believe that you might be using Pidgin using DBus, as you using names as Buddy, which the rest of us call Contact, which is a lot more sane.

    Also, please read the Qt coding style guide (plus the API guide etc – all available on the wiki found on their gitorious subdomain). That will tell you to never using names like *Ctrl, but to spell it out, thus *Controller.

    It is a good read!

  2. Anderson Briglia
    May 22nd, 2009 at 09:43 | #2

    Actually we’ve followed the coding style by astyle-kde script. I already read the stuff about variable and class names, but I think it a little bit *bloat*. Ok, We were kernel programmers, so, give us a chance. :)
    We are not using Telepathy. We are using a daemon, the same used in Carman (which uses libpurple and DBus).

  3. Kenneth Christiansen
    May 23rd, 2009 at 13:39 | #3

    Yeah I guessed that… the demo looks cool, btw :-)

    Anyway you should really take a look at TelepathyQt4, it is pretty good and will surely be used on Maemo in the future, as telepathy is already used today.

  1. No trackbacks yet.