近些天用qt 作项目,遇到参数界面.偷闲写个mvp模式示例.
mvp模式重要的有两点
1 低耦合: 界面与后端数据类,不直接引用,可方便替换.
2 形成界面驱动-界面更新的闭环.:通过函数指针类技术,让数据自动回流.
MVP (Model-View-Presenter)
视图(View):
- 接收用户的交互请求并根據需求展示数据给用户
- 响應的數据可以是一個Model或者多個Model的混合
主持人(Presenter):
- View 和 Mode的連接器
- 接收 View 的要求 并給对应的Model去處理
模型(Model):
- 負責數据 (增加,删除,更改,查詢)
- 相關的业务逻辑,而不是在Presenter(因為會使Presenter變得臃腫)
参考:
一文读懂MVC、MVP和MVVM架构
直接上代码,
QT5.9.0 ,C++11
view, 包括一个设置数据的接口与一个要求数据的信号(类似于函数指针);诉讼诉讼诉讼诉讼诉讼诉讼诉讼诉讼诉讼诉讼诉讼诉讼诉讼诉讼诉讼
//.h
class DialogView : public QDialog
{
Q_OBJECT
public:
explicit DialogView(QWidget *parent = nullptr);
~DialogView();
void UpdateVidw(UerData data);
signals:
void UpdateView_Signal();
private slots:
void on_btnRefresh_clicked();
private:
Ui::DialogView *ui;
};
//.cpp
void DialogView::UpdateVidw(UerData data)
{
this->ui->comboBox->setCurrentIndex(data.SelIdx);
this->ui->lineEdit->setText(data.txt);
this->ui->spinBox->setValue(data.num);
this->ui->timeEdit->setTime(data.utime);
this->ui->dial->setValue(data.SelNum);
}
void DialogView::on_btnRefresh_clicked()
{
emit this->UpdateView_Signal();
}
流通使用的数据结构
struct UerData
{
public:
int SelIdx;
QString txt;
int num;
QTime utime;
int SelNum;
};
Model. 提供数据源
//.h
class DataModel
{
public:
UerData data;
void UpdateData();
};
//.cpp
void DataModel::UpdateData()
{
// 模拟从外网,下位机设备等拿取数据.
qsrand(QTime::currentTime().msec());
data.SelIdx = qrand()%3;
data.txt = data.SelIdx == 1 ? "NUm1" : "deg2";
data.utime = QTime::currentTime();
data.num = qrand() % 1000;
data.SelNum = qrand() % 100;
}
Presenter, 提供连接View 和model的方法
//.h
class Presenter : public QObject
{
Q_OBJECT
public:
explicit Presenter(DataModel* model, DialogView* view, QObject *parent = nullptr);
public slots:
void fetchData();
private:
DataModel* m_model;
DialogView* m_view;
};
// .cpp
Presenter::Presenter(DataModel *model, DialogView *view, QObject *parent)
: QObject{parent}
{
this->m_model = model;
this->m_view = view;
// 通过fetchData函数 ,绑定view与 model ,类似给函数指针赋值;
QObject::connect(view, SIGNAL(UpdateView_Signal()),
this, SLOT(fetchData()));
}
void Presenter::fetchData()
{
this->m_model->UpdateData();
this->m_view->UpdateVidw(m_model->data);
}
使用代码:
DialogView *dlg = new DialogView();
DataModel *model = new DataModel();
Presenter *p = new Presenter(model, dlg);
dlg->exec();
最后实现效果如下:
点击"更新"按钮数据自动更新.