最近做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 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();
}
四、代码下载
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