最近做qt 项目,发现网上基于MVP设计模式的QT例程很少,这里写一个demo示例可作为参考:
一、简要概述
MVP是由MVC发展而来,总体目的与作用相同。都是为了软件构架有层次之分,使得核心逻辑、界面控制、数据这三者分层清晰明了。减少了三者之间的逻辑耦合与功能耦合。也是的代码清晰易读。从而减少因写代码造成的bug。也增加了软件整体的稳定性。
二、代码实现
Interface接口:
interface.h文件
class Interface {public:virtual ~Interface() {};virtual void update_image(const std::string path) = 0;virtual void update_message(const std::string data) = 0;
};
model类:
model.h文件
class Model
{
public:explicit Model(Interface *i = 0);std::string get_data();
public:void run();void work();private:std::string image_path;std::string data;Interface *m_interface;
};
model.cpp文件
Model::Model(Interface *i) : m_interface(i)
{image_path = "D:/WorkSpace/QT/MvpTest/";data = "Hello MVP!!!";//启动一个线程run();
}std::string Model::get_data()
{return data;
}static int count = 0;
void Model::work()
{while (1) {sleep(1);time_t result = time(NULL);data = std::to_string(result);if(count++ % 5 == 0){m_interface->update_message("Auto:"+data); //更新界面显示if(count % 2 == 0) {m_interface->update_image(image_path+"picture_normal.jpg");}else{m_interface->update_image(image_path+"picture_blue.jpg");}}}
}void Model::run()
{std::thread work_thread(std::bind(&Model::work, this));work_thread.detach();
}
view类:
view.h文件
class View : public QWidget
{Q_OBJECT
public:explicit View(QWidget *parent = nullptr);void updateImage(const QString& path);void updateMessage(const QString& message);signals:void buttonClicked();private:QLabel label;QLabel image_label;QPushButton button;
};
view.cpp文件
View::View(QWidget *parent) : QWidget(parent)
{this->resize(800,600); //设置窗口大小//设置背景色QPalette palette(this->palette());palette.setColor(QPalette::Background, Qt::lightGray);this->setPalette(palette);// 创建一个QFont对象,设置字体label.setFont(QFont("微软雅黑",42,QFont::Bold));// 设置对齐方式为居中对齐label.setAlignment(Qt::AlignCenter);// 设置文本内容label.setText("Hello MVP!");// 显示图片image_label.setScaledContents(true); //show allimage_label.setPixmap(QPixmap("D:/WorkSpace/QT/MvpTest/picture_normal.jpg"));//设置按钮内容button.setText("Click me!");button.setStyleSheet("QPushButton { background-color: white; color: black; }");button.resize(50,30);//排版QVBoxLayout* layout = new QVBoxLayout(this);layout->addWidget(&label);layout->addWidget(&image_label);layout->addWidget(&button);connect(&button, &QPushButton::clicked, this, &View::buttonClicked);
}void View::updateImage(const QString& path)
{image_label.setScaledContents(true); //show allimage_label.setPixmap(QPixmap(path));
}void View::updateMessage(const QString& message)
{label.setText(message);
}
presenter类:
presenter.h文件
class Presenter : public QObject, public Interface
{Q_OBJECT
public:explicit Presenter(QObject *parent = nullptr);~Presenter() override;void showView();//接口函数void update_image(const std::string path) override;void update_message(const std::string data) override;public slots:void onButtonClicked();private:Model *model = new Model(this);View view;
};
presenter.cpp文件
Presenter::Presenter(QObject *parent) : QObject(parent)
{//绑定按键指令和按键动作connect(&view, &View::buttonClicked, this, &Presenter::onButtonClicked);
}Presenter::~Presenter()
{delete model;
}void Presenter::showView()
{view.show();
}/** 通过信号和槽的方式,响应view层的按键指令,更新界面显示*/
void Presenter::onButtonClicked()
{view.updateMessage(QString::fromStdString(model->get_data()));
}/** 通过接口的方式被model层调用,用于更新显示图片*/
void Presenter::update_image(const std::string path)
{printf("path:%s\n",path.c_str());view.updateImage(QString::fromStdString(path));
}/** 通过接口的方式被model层调用,用于更新显示消息*/
void Presenter::update_message(const std::string data)
{printf("data:%s\n",data.c_str());view.updateMessage(QString::fromStdString(data));
}
三、使用demo
int main(int argc, char *argv[])
{QApplication a(argc, argv);Presenter presenter;presenter.showView();return a.exec();
}
四、代码下载
GitHub - GitHubLuGeng/MVP_Demo: 基于QT实现的一个MVP架构demo,欢迎 star or fork!
这种方式是最典型的mvp设计模式实现,但是当接口越来越多的时候,presenter会越来越大,还有一种变种mvp设计模式,只使用model + View + Interface的方式,每次新增接口只需要在Interface中增加对应接口的虚函数即可:
https://download.csdn.net/download/lu_linux/88507037