TouchGFX user interfaces follow an architectural pattern known as Model-View-Presenter (MVP) which is a derivation of the Model-View-Controller (MVC) pattern. Both of them are widely used for building user interface applications.
/************ Model.hpp ************/
class ModelListener;
class Model
{
public:
Model();
void bind(ModelListener* listener)
{
modelListener = listener;
}
void tick();
protected:
ModelListener* modelListener;
};
Model()
: C++构造函数,与class名称相同且没有任何返回值。Model::tick()
: One way is to perform a task check in the Model class once in every frame.
/************ ModelListener.hpp ************/
class ModelListener
{
public:
ModelListener() : model(0) {}
virtual ~ModelListener() {}
void bind(Model* m)
{
model = m;
}
protected:
Model* model;
};
1.ModelListener() : model(0) {}
:构造函数,以初始化列表形式将内部私有变量model
初始化为NULL
。
2. virtual ~ModelListener() {}
:构造函数重载,~
用在函数之前,表示该函数为构造函数。virtual
则表示该函数为虚函数。
/************ Screen1Presenter.hpp ************/
using namespace touchgfx;
class Screen1View;
class Screen1Presenter : public touchgfx::Presenter, public ModelListener
{
public:
Screen1Presenter(Screen1View& v);
/**
* The activate function is called automatically when this screen is "switched in"
* (ie. made active). Initialization logic can be placed here.
*/
virtual void activate();
/**
* The deactivate function is called automatically when this screen is "switched out"
* (ie. made inactive). Teardown functionality can be placed here.
*/
virtual void deactivate();
virtual ~Screen1Presenter() {};
private:
Screen1Presenter();
Screen1View& view;
};
Screen1Presenter(Screen1View& v);
默认的构造函数以View
指针为入参,在官方提供的函数实现中,入参v
用于初始化私有变量Screen1View& view
。
Screen1Presenter::Screen1Presenter(Screen1View& v)
: view(v)
{
}
/************ Screen1View.hpp ************/
class Screen1View : public Screen1ViewBase
{
public:
Screen1View();
virtual ~Screen1View() {}
virtual void setupScreen();
virtual void tearDownScreen();
/** user defined function **/
virtual void addRandomPoint();
virtual void clearGraph();
virtual void handleTickEvent();
protected:
int tickCounter;
};
Screen1View.hpp
中用到的知识点与前面介绍文件重复,不在此赘述。
现总结如下:
Model
是TouchGFX MVP架构中生命周期最长的组件,不会随着Screen的切换被清除,所以,如果后台程序需要与UI组件进行通信,例如创建消息队列或邮箱,应当在Model
的构造函数中进行创建和初始化。确切来讲,应当是在virtual ~ModelListener() {}
函数中。但是,RTOS组件的初始化应尽量设置在内核启动之前,实际操作中个人不推荐把与UI通信的系统组件放置在model层中进行初始化。Presenter
是ModelListener
的子类,而Model
和ModelListener
通过指针变量相互绑定,因此Presenter
可以访问在Model.cpp
(属于Model
类) 中定义的函数。Presenter
的构造函数以指向View
的指针作为入参,用来初始化内部私有变量view
,因此,Presenter
同样也可以访问View
中的函数。- 总结 2,3两点,我们可以发现
Presenter
起到桥梁的作用,将Model
和View
连接到一起。View
中定义的函数用于直接操作UI组件,Model
则负责与后台对接,例如处理信号量或消息队列。
参考资料
C++类中成员变量的初始化有两种方式
C++11 中的继承构造函数
C++构造函数的重载
c++ 中. 和 ->,波浪号 ~ 符号怎么用
C++中virtual(虚函数)的用法
TouchGFX MVP通信架构
The Screen Concept - TouchGFX
How to update other tasks from the TouchGFX GUI
How to Update the TouchGFX GUI from other tasks