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

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

一、简要概述

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

QT实现的一个MVP设计模式demo_第1张图片

二、代码实现

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 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类:

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();
}

QT实现的一个MVP设计模式demo_第2张图片

四、代码下载

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

 

你可能感兴趣的:(QT,笔记,mvp,qt,设计模式)