• QT实现的一个MVP设计模式demo


    最近做qt 项目,发现网上基于MVP设计模式的QT例程很少,这里写一个demo示例可作为参考:

    一、简要概述

    MVP是由MVC发展而来,总体目的与作用相同。都是为了软件构架有层次之分,使得核心逻辑、界面控制、数据这三者分层清晰明了。减少了三者之间的逻辑耦合与功能耦合。也是的代码清晰易读。从而减少因写代码造成的bug。也增加了软件整体的稳定性。

    二、代码实现

    Interface接口:

    interface.h文件

    1. class Interface {
    2. public:
    3. virtual ~Interface() {};
    4. virtual void update_image(const std::string path) = 0;
    5. virtual void update_message(const std::string data) = 0;
    6. };
    model类:

    model.h文件

    1. class Model
    2. {
    3. public:
    4. explicit Model(Interface *i = 0);
    5. std::string get_data();
    6. public:
    7. void run();
    8. void work();
    9. private:
    10. std::string image_path;
    11. std::string data;
    12. Interface *m_interface;
    13. };

    model.cpp文件

    1. Model::Model(Interface *i) : m_interface(i)
    2. {
    3. image_path = "D:/WorkSpace/QT/MvpTest/";
    4. data = "Hello MVP!!!";
    5. //启动一个线程
    6. run();
    7. }
    8. std::string Model::get_data()
    9. {
    10. return data;
    11. }
    12. static int count = 0;
    13. void Model::work()
    14. {
    15. while (1) {
    16. sleep(1);
    17. time_t result = time(NULL);
    18. data = std::to_string(result);
    19. if(count++ % 5 == 0)
    20. {
    21. m_interface->update_message("Auto:"+data); //更新界面显示
    22. if(count % 2 == 0) {
    23. m_interface->update_image(image_path+"picture_normal.jpg");
    24. }
    25. else{
    26. m_interface->update_image(image_path+"picture_blue.jpg");
    27. }
    28. }
    29. }
    30. }
    31. void Model::run()
    32. {
    33. std::thread work_thread(std::bind(&Model::work, this));
    34. work_thread.detach();
    35. }
    view类:

    view.h文件

    1. class View : public QWidget
    2. {
    3. Q_OBJECT
    4. public:
    5. explicit View(QWidget *parent = nullptr);
    6. void updateImage(const QString& path);
    7. void updateMessage(const QString& message);
    8. signals:
    9. void buttonClicked();
    10. private:
    11. QLabel label;
    12. QLabel image_label;
    13. QPushButton button;
    14. };

    view.cpp文件

    1. View::View(QWidget *parent) : QWidget(parent)
    2. {
    3. this->resize(800,600); //设置窗口大小
    4. //设置背景色
    5. QPalette palette(this->palette());
    6. palette.setColor(QPalette::Background, Qt::lightGray);
    7. this->setPalette(palette);
    8. // 创建一个QFont对象,设置字体
    9. label.setFont(QFont("微软雅黑",42,QFont::Bold));
    10. // 设置对齐方式为居中对齐
    11. label.setAlignment(Qt::AlignCenter);
    12. // 设置文本内容
    13. label.setText("Hello MVP!");
    14. // 显示图片
    15. image_label.setScaledContents(true); //show all
    16. image_label.setPixmap(QPixmap("D:/WorkSpace/QT/MvpTest/picture_normal.jpg"));
    17. //设置按钮内容
    18. button.setText("Click me!");
    19. button.setStyleSheet("QPushButton { background-color: white; color: black; }");
    20. button.resize(50,30);
    21. //排版
    22. QVBoxLayout* layout = new QVBoxLayout(this);
    23. layout->addWidget(&label);
    24. layout->addWidget(&image_label);
    25. layout->addWidget(&button);
    26. connect(&button, &QPushButton::clicked, this, &View::buttonClicked);
    27. }
    28. void View::updateImage(const QString& path)
    29. {
    30. image_label.setScaledContents(true); //show all
    31. image_label.setPixmap(QPixmap(path));
    32. }
    33. void View::updateMessage(const QString& message)
    34. {
    35. label.setText(message);
    36. }
    presenter类:

    presenter.h文件

    1. class Presenter : public QObject, public Interface
    2. {
    3. Q_OBJECT
    4. public:
    5. explicit Presenter(QObject *parent = nullptr);
    6. ~Presenter() override;
    7. void showView();
    8. //接口函数
    9. void update_image(const std::string path) override;
    10. void update_message(const std::string data) override;
    11. public slots:
    12. void onButtonClicked();
    13. private:
    14. Model *model = new Model(this);
    15. View view;
    16. };

    presenter.cpp文件

    1. Presenter::Presenter(QObject *parent) : QObject(parent)
    2. {
    3. //绑定按键指令和按键动作
    4. connect(&view, &View::buttonClicked, this, &Presenter::onButtonClicked);
    5. }
    6. Presenter::~Presenter()
    7. {
    8. delete model;
    9. }
    10. void Presenter::showView()
    11. {
    12. view.show();
    13. }
    14. /*
    15. * 通过信号和槽的方式,响应view层的按键指令,更新界面显示
    16. */
    17. void Presenter::onButtonClicked()
    18. {
    19. view.updateMessage(QString::fromStdString(model->get_data()));
    20. }
    21. /*
    22. * 通过接口的方式被model层调用,用于更新显示图片
    23. */
    24. void Presenter::update_image(const std::string path)
    25. {
    26. printf("path:%s\n",path.c_str());
    27. view.updateImage(QString::fromStdString(path));
    28. }
    29. /*
    30. * 通过接口的方式被model层调用,用于更新显示消息
    31. */
    32. void Presenter::update_message(const std::string data)
    33. {
    34. printf("data:%s\n",data.c_str());
    35. view.updateMessage(QString::fromStdString(data));
    36. }

    三、使用demo

    1. int main(int argc, char *argv[])
    2. {
    3. QApplication a(argc, argv);
    4. Presenter presenter;
    5. presenter.showView();
    6. return a.exec();
    7. }

    四、代码下载

    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

     

  • 相关阅读:
    离线数据开发流程小案例-图书馆业务数据
    PC_高速缓冲存储器cache和局部性原理
    JAVA毕业设计高校墨香文学社管理系统计算机源码+lw文档+系统+调试部署+数据库
    整数划分——DP
    大屏小程序探索实践 | Cube 技术解读
    PMP最新考纲难在哪里?面对新教材的来袭,我该怎么计划考试?
    Spring Cloud Stream 消息驱动微服务 相关图形,dljd,cat - spring cloud alibaba,p153完成
    Kafka-exporter监控消费速度与生产速度差异规则
    C语言实现猜数字小游戏项目实战(基于srand函数、rand函数,Switch语句、while循环、if条件判据等)
    【0236】聊一聊PG内核中的命令标签(Command Tags、CommandTag、tag_behavior)
  • 原文地址:https://blog.csdn.net/lu_linux/article/details/134157649