Model-View-Presenter(MVP) Design Pattern in Qt Application

From Qt Wiki
Jump to: navigation, search

Can we implement MVP(Model-View-Presenter) design pattern using Qt's Signal and slot mechanism.

We will try to create a Qt application with MVP design pattern.

First of all What is MVP design pattern? MVP is a user interface architectural pattern engineered to facilitate separation of logic out of the view and into the presenter.

First we refer to existing documentation about Model-View-Presenter.MVP Wiki documentation says like this. a)The Presenter is common to multiple views. b)The model is an interface defining the data to be displayed or otherwise acted upon in the user interface. c)The View is kept as thin and ignorant as possible.

In MVP the presenter assumes the functionality of the "middle-man". In MVP, all presentation logic (Signal and slots and connect statements)is pushed to the presenter class.

Remaining views only has the implementation to display it self.

I will add the code snippets for the three views and its presenter class.

I have an application with Three Views the object interaction happens via the Presenter class.

ViewOne,ViewTwo,ViewThree classes declaration and implementation.

#include <QWidget>

namespace Ui {
class ViewOne;
}

class ViewOne : public QWidget
{
    Q_OBJECT

public:
    explicit ViewOne(QWidget *parent = 0);
    ~ViewOne();

private:
    Ui::ViewOne *ui;
};
#include "viewone.h"
#include "ui_viewone.h"

ViewOne::ViewOne(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ViewOne)
{
    ui->setupUi(this);
    QObject::connect(ui->pushButton,SIGNAL(clicked()),this,SIGNAL(ViewTwoButtonclicked()));

}

ViewOne::~ViewOne()
{
    delete ui;
}
#include <QWidget>

class ViewTwo : public QWidget
{
    Q_OBJECT
public:
    explicit ViewTwo(QWidget *parent = 0);

signals:
    void ViewTwoButtonClicked();
    void ViewThreeButtonClicked();

public slots:
    void onViewTwoButtonClicked();

};
#include "viewtwo.h"
#include <QVBoxLayout>
#include <QPushButton>

ViewTwo::ViewTwo(QWidget *parent) :
    QWidget(parent)
{
    QVBoxLayout *vLay = new QVBoxLayout;
    QPushButton *button = new QPushButton("Open View Three");
    vLay->addWidget(button);
    setLayout(vLay);
    setWindowTitle("View Two");
    QObject::connect(button,SIGNAL(clicked()),this,SIGNAL(ViewTwoButtonClicked()));
}


void ViewTwo::onViewTwoButtonClicked()
{
     this->show();
}
#include <QWidget>

class ViewThree : public QWidget
{
    Q_OBJECT
public:
    explicit ViewThree(QWidget *parent = 0);

signals:

public slots:
    void onViewThreeButtonClicked();
};
#include "viewthree.h"
#include <QLabel>
#include <QVBoxLayout>
ViewThree::ViewThree(QWidget *parent) :
    QWidget(parent)
{
    QVBoxLayout *vLay = new QVBoxLayout;
    QLabel *label = new QLabel("In View Three");
    label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    vLay->addWidget(label);
    setLayout(vLay);
    setWindowTitle("View Three");
}


void ViewThree::onViewThreeButtonClicked()
{
 this->show();
}
#include <QObject>

#include "viewone.h"
#include "viewtwo.h"
#include "viewthree.h"

class Presenter : public QObject
{
    Q_OBJECT
public:

    Presenter(ViewOne* vOne, ViewTwo* vTwo, ViewThree *vThree);

    void ConnectToViewTwo(QObject* ,QObject*);
    void ConnectToViewThree(QObject *viewTwo, QObject*);

signals:
    void ViewTwoButtonClicked();
    void ViewThreeButtonClicked();

};
#include "presenter.h"
#include "viewone.h"
#include "viewtwo.h"
#include "viewthree.h"
#include "presenter.h"

Presenter::Presenter(ViewOne *viewOne, ViewTwo *viewTwo,ViewThree* vThree)
{
    ConnectToViewTwo(viewOne,viewTwo);
    ConnectToViewThree(viewTwo,vThree);

}

void Presenter::ConnectToViewTwo(QObject *viewOne,QObject *viewTwo)
{
    QObject::connect(viewOne,SIGNAL(ViewTwoButtonClicked()),this,SIGNAL(ViewTwoButtonClicked()));
    QObject::connect(this,SIGNAL(ViewTwoButtonClicked()),viewTwo,SLOT(onViewTwoButtonClicked()));


}

void Presenter::ConnectToViewThree(QObject *viewTwo,QObject * ViewThree)
{
    QObject::connect(viewTwo,SIGNAL(ViewTwoButtonClicked()),this,SIGNAL(ViewThreeButtonClicked()));
    QObject::connect(this,SIGNAL(ViewThreeButtonClicked()),ViewThree,SLOT(onViewThreeButtonClicked()));

}
#include "viewone.h"
#include "viewtwo.h"
#include "viewthree.h"
#include "presenter.h"

#include <QApplication>

static ViewOne* v1 = NULL;
static ViewTwo* v2 = NULL;
static ViewThree* v3 = NULL;
static Presenter* pt = NULL;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    v1 = new ViewOne();
    v2 = new ViewTwo();
    v3 = new ViewThree();
    pt = new Presenter(v1,v2,v3);
    v2->setGeometry(v1->x()+v1->width(),v1->y()+v1->height(),v1->width(),v1->height());
    v3->setGeometry(v2->x()+v2->width(),v2->y()+v2->height(),v2->width(),v2->height());

    v1->show();
    return a.exec();
}