最近做qt 项目,发现网上基于MVP设计模式的QT例程很少,这里写一个demo示例可作为参考:
MVP是由MVC发展而来,总体目的与作用相同。都是为了软件构架有层次之分,使得核心逻辑、界面控制、数据这三者分层清晰明了。减少了三者之间的逻辑耦合与功能耦合。也是的代码清晰易读。从而减少因写代码造成的bug。也增加了软件整体的稳定性。

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.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.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 all
- image_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 all
- image_label.setPixmap(QPixmap(path));
- }
-
- void View::updateMessage(const QString& message)
- {
- label.setText(message);
- }
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));
- }
- 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