STM32单片机项目实例:基于TouchGFX的智能手表设计(7)MVP架构下的交互逻辑设计

news2024/7/6 19:11:21

STM32单片机项目实例:基于TouchGFX的智能手表设计(7)MVP架构下的交互逻辑设计

目录

一、概述

二、MVP架构下的交互逻辑


一、概述

  本文例程是基于 TouchGFX 的智能手表设计—Designer 软件 UI 设计的例程 0B-2_STM32U575_MVP_Interactive工程的拷贝,用于MVP架构下的逻辑代码添加。

二、MVP架构下的交互逻辑

  将资料光盘中的0B-2_STM32U575_MVP_Interactive例程拷贝至工程目录,并将文件夹重命名为0B-3_STM32U575_MVP_Interactive,打开…\0B-3_STM32U575_MVP_Interactive\TouchGFX 下的0B-2_STM32U575_MVP_Interactive.touchgfx,点击DialPage,在Interactions增加GoToAPP的硬件交互,用于表盘页面与APP页面的切换(硬件按键触发)。

  点击ApplicationPage,在Interactions增加GoToDial的硬件交互,用于APP页面与表盘页面的切换(硬件按键触发)。

点击右下角的</>.生成代码,打开MDK工程,进行工程的全编译。

  点击工程管理目录下的gui,打开MenuElement.cpp与MenuElement.hpp,在MenuElement.hpp中添加Scroll Wheel的相关函数声明。

#ifndef MENUELEMENT_HPP
#define MENUELEMENT_HPP
//
#include <gui_generated/containers/MenuElementBase.hpp>
#include <BitmapDatabase.hpp>
#include <math.h>
//
class MenuElement : public MenuElementBase
{
public:
    MenuElement();
    virtual ~MenuElement() {}
		//
    virtual void initialize();
		int8_t number;			
		void offset(int16_t x);
		virtual void setY(int16_t y);
		void setNumber(int no);	
protected:
		//声明点击事件回调函数
		Callback<MenuElement, const touchgfx::ScalableImage & , const touchgfx::ClickEvent &> imageClickHandler;
		//声明点击事件处理函数
    void image_click_handler(const touchgfx::ScalableImage &image , const touchgfx::ClickEvent &event);
};
#endif // MENUELEMENT_HPP

在MenuElement.cpp文件中增加以下代码:

#include <gui/containers/MenuElement.hpp>

MenuElement::MenuElement():imageClickHandler(this,&MenuElement::image_click_handler)
{

}
//
void MenuElement::initialize()
{
    MenuElementBase::initialize();
}
//重新设置组件的x轴位置
void MenuElement::offset(int16_t x)
{
		//设置图标位置
		icon.moveTo(20 + x, icon.getY());
		//设置文本位置,文本跟随图标移动
		text.moveTo(43 + icon.getX(), 5 + icon.getY());	
}
//点击图标后触发事件
void MenuElement::image_click_handler(const touchgfx::ScalableImage &image , const touchgfx::ClickEvent &event)
{
		touchgfx::ClickEvent::ClickEventType type = event.getType();
		if(type==touchgfx::ClickEvent::ClickEventType::PRESSED)
		{
				if(&image == &icon)
				{
						switch(number % 7)
						{
								case 0:		//健康监测事件触发,健康监测图标与文字
									icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_PRESSED_HEALTH_ID));
									icon.invalidate();
									//
									break;
								case 1:		//姿态读取事件触发,姿态读取图标与文字
									icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_PRESSED_6050_ID));
									icon.invalidate();
									//
break;
								case 2:		//事件触发,环境信息图标与文字
									icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_PRESSED_TEMP_ID));
									icon.invalidate();
									//
								break;
								case 3:		//芯片信息事件触发,芯片信息图标与文字
									icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_PRESSED_CHIP_ID));
									icon.invalidate();
									//
									break;
								case 4:		//振动控制事件触发,振动控制图标与文字
									icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_PRESSED_BUZZER_ID));
									icon.invalidate();
									//
									break;
								case 5:		//电池电量事件触发,电池电量图标与文字
									icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_PRESSED_BATTERY_ID));
									icon.invalidate();
									//
									break;
								case 6:		//无线连接事件触发,无线连接图标与文字
									icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_PRESSED_WIFI_ID));
									icon.invalidate();
									//
									break;
						}
				}
		}
}
//
void MenuElement::setY(int16_t y)
{
		MenuElementBase::setY(y);
		//设定圆弧的半径,表盘直径-图标半径
		const int circleRadius = 210;
//获取Y轴坐标信息	
		y = y + getHeight()/2 - 240 / 2;
		//勾股定理计算X轴位置
		float x_f = circleRadius - sqrtf(abs((float)(circleRadius * circleRadius) - (y * y)));
		//重新设置组件的x轴位置
		offset((int16_t)(x_f));
}
//对const的buf指针做强转去掉const
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
//设置图标与文本
void MenuElement::setNumber(int no)
{
		icon.setClickAction(imageClickHandler);
		//修改图标
		switch(no % 7)
		{
				case 0:		//无触发事件时,健康监测图标与文字
					icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_HEALTH_ID));
					Unicode::snprintf(textBuffer, TEXT_SIZE, (Unicode::UnicodeChar*)L"健康监测");
					break;
				case 1:		//无触发事件时,姿态读取图标与文字
					icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_6050_ID));
					Unicode::snprintf(textBuffer, TEXT_SIZE, (Unicode::UnicodeChar*)L"姿态感知");
					break;
				case 2:		//无触发事件时,环境信息图标与文字
					icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_TEMP_ID));
					Unicode::snprintf(textBuffer, TEXT_SIZE, (Unicode::UnicodeChar*)L"环境信息");
					break;
				case 3:		//无触发事件时,芯片信息图标与文字
					icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_CHIPINFO_ID));
					Unicode::snprintf(textBuffer, TEXT_SIZE, (Unicode::UnicodeChar*)L"芯片信息");
					break;
				case 4:		//无触发事件时,振动控制图标与文字
					icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_BUZZER_ID));
					Unicode::snprintf(textBuffer, TEXT_SIZE, 
(Unicode::UnicodeChar*)L"外部控制");
					break;
				case 5:		//无触发事件时,电池电量图标与文字
					icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_BATTERY_ID));
					Unicode::snprintf(textBuffer, TEXT_SIZE, (Unicode::UnicodeChar*)L"电池电量");
					break;
				case 6:		//无触发事件时,无线连接图标与文字
					icon.setBitmap(touchgfx::Bitmap(BITMAP_APPLICATIONPAGE_IMAGE_WIFI_ID));
					Unicode::snprintf(textBuffer, TEXT_SIZE, (Unicode::UnicodeChar*)L"无线连接");
					break;
		}
		number = no;
}
点击ApplicationPageView.cpp,打开ApplicationPageView.hpp文件,添加APP页面的图标滚动与字体更变。
#ifndef APPLICATIONPAGEVIEW_HPP
#define APPLICATIONPAGEVIEW_HPP

#include <gui_generated/applicationpage_screen/ApplicationPageViewBase.hpp>
#include <gui/applicationpage_screen/ApplicationPagePresenter.hpp>

class ApplicationPageView : public ApplicationPageViewBase
{
public:
    ApplicationPageView();
    virtual ~ApplicationPageView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
		//实现APP页面的滚动图标与文字更新
		virtual void AppScrollWheelUpdateItem(MenuElement& item,int16_t itemIndex)
		{
			item.setNumber(itemIndex);
		}
protected:
};

#endif // APPLICATIONPAGEVIEW_HPP

  点击MDK全编译,完成后,在Designer软件中设置ApplicationPage为启动窗口,点击右下角的仿真。

  也可以在MDK中进行开发板的下载,下载完成后,复位开发板。FS-STM32U5开发板屏幕的展示效果与PC端仿真相同。

开发板的显示效果

PC端Designer仿真效果

打开ApplicationPageView.cpp /ApplicationPageView.hppApplicationPagePresenter.cpp/ ApplicationPagePresenter.hpp / Model.cpp / Model.hpp/ModelListener.hpp文件,添加硬件按键的触发。

ApplicationPageView.cpp文件中添加页面的跳转。

#include <gui/applicationpage_screen/ApplicationPageView.hpp>

//
ApplicationPageView::ApplicationPageView()
{

}
//
void ApplicationPageView::setupScreen()
{
    ApplicationPageViewBase::setupScreen();
}
//
void ApplicationPageView::tearDownScreen()
{
    ApplicationPageViewBase::tearDownScreen();
}
//页面跳转
void ApplicationPageView::AppPageChange(uint8_t newFiveKeyFunc)
{
		handleKeyEvent(newFiveKeyFunc);
}

ApplicationPageView.hpp中添加函数声明

 

#ifndef APPLICATIONPAGEVIEW_HPP
#define APPLICATIONPAGEVIEW_HPP

#include <gui_generated/applicationpage_screen/ApplicationPageViewBase.hpp>
#include <gui/applicationpage_screen/ApplicationPagePresenter.hpp>

class ApplicationPageView : public ApplicationPageViewBase
{
public:
    ApplicationPageView();
    virtual ~ApplicationPageView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
		//页面跳转
		void AppPageChange(uint8_t newFiveKeyFunc);
		//实现APP页面的滚动图标与文字更新
		virtual void AppScrollWheelUpdateItem(MenuElement& item,int16_t itemIndex)
		{
			item.setNumber(itemIndex);
		}
protected:
	 
};

#endif // APPLICATIONPAGEVIEW_HPP

ApplicationPagePresenter.cpp文件中添加APP页面任务使能与页面切换代码。

#include <gui/applicationpage_screen/ApplicationPageView.hpp>
#include <gui/applicationpage_screen/ApplicationPagePresenter.hpp>

ApplicationPagePresenter::ApplicationPagePresenter(ApplicationPageView& v)
    : view(v)
{

}
//
void ApplicationPagePresenter::activate()
{
		ApplicationPagePresenterState(true);	
}
//
void ApplicationPagePresenter::deactivate()
{
		ApplicationPagePresenterState(false);	
}
//ApplicationPagePresenter状态
void ApplicationPagePresenter::ApplicationPagePresenterState(bool enable)
{
		if(enable == true)
			model->ApplicationPageViewTask(true);
		else
			model->ApplicationPageViewTask(false);
}
//页面跳转
void ApplicationPagePresenter::AppPageChange(uint8_t newFiveKeyFunc)
{
		view.AppPageChange(newFiveKeyFunc);	
}

ApplicationPagePresenter.hpp文件中添加函数声明。

#ifndef APPLICATIONPAGEPRESENTER_HPP
#define APPLICATIONPAGEPRESENTER_HPP

#include <gui/model/ModelListener.hpp>
#include <mvp/Presenter.hpp>

using namespace touchgfx;

class ApplicationPageView;

class ApplicationPagePresenter : public touchgfx::Presenter, public ModelListener
{
public:
    ApplicationPagePresenter(ApplicationPageView& 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 ~ApplicationPagePresenter() {};
			
		//ApplicationPagePresenter状态
		void ApplicationPagePresenterState(bool enable);
		//页面跳转	
		virtual void AppPageChange(uint8_t newFiveKeyFunc);
private:
    ApplicationPagePresenter();

    ApplicationPageView& view;
};
#endif // APPLICATIONPAGEPRESENTER_HPP

Model.cpp中添加与底层驱动的相关获取与控制代码。

#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>

#if defined LINK_HARDWARE 	//TuchGFX仿真与实际硬件操作隔离
	//头文件包含
	extern "C"
	{
		#include "user_app.h"
	}
	//底层数据
	extern volatile SHT20_TemRH_Val gTemRH_Val;
	extern RTC_DateTypeDef gSystemDate;  //获取日期结构体
	extern RTC_TimeTypeDef gSystemTime;   //获取时间结构体
	extern gTask_BitDef gTaskStateBit;  //任务执行过程中使用到的标志位
	extern gTask_MarkEN gTaskEnMark;  //系统任务使能标识
	extern volatile StruAP3216C_Val gAP3216C_Val;	//AP3216数据结构
	extern volatile uint8_t gLastTimeSeconds;	//上一次的时间
	extern volatile float pitch,roll,yaw; //欧拉角
	extern unsigned long gSportStep;	//运动步数
	extern wifiRSSI ao_wifiRSSI;
	
	extern uint8_t gFiveKeyFunc;	//定义的五向按键值功能	
	
	extern volatile uint16_t gCurrentVal;	//资源扩展板电流,通道IN8   
	extern volatile uint16_t gVoltageVal;	//资源扩展板电压,通道IN9  
	extern volatile uint16_t gChipTempVal;//内部参考电压,通道IN12  
	extern volatile uint16_t gVrefVal;		//内部参考电压,通道IN13   	
	extern volatile uint16_t gVbatVal;		//RTC电池电压,通道IN14  

	extern int32_t n_heart_rate;   //heart rate value=n_heart_rate/4,采样率100sps,max30102设置4点求平均
	extern int32_t n_sp02; //SPO2 value
	extern int8_t ch_spo2_valid;   //indicator to show if the SP02 calculation is valid
	extern int8_t  ch_hr_valid;    //indicator to show if the heart rate calculation is valid
	extern uint8_t gWiFiInfo[40];	//用于通知View界面的Text文本显示
	//
	volatile uint8_t gSwitchSpace = 0x00;	//页面切换的时间间隙
	static int32_t gHeartRate = 0;  //表盘页面的心率数据
#else //Designer仿真
	#include <ctime>
	#ifndef _MSC_VER
	#include <sys/time.h>
#endif /* _MSC_VER*/
	//
	volatile uint8_t gBacklightVal = 50;	//背光值,默认50%
#endif
/**********************************TouchGFX与底层间的访问**********************************/
Model::Model() : modelListener(0)
{

}
//
void Model::tick()
{
	static uint8_t tickCount = 0;	//减少数据上传的次数,优化界面刷新
	tickCount++;	

#if defined LINK_HARDWARE
	//
	if(gSwitchSpace != 0) gSwitchSpace--;	
	/********************************硬件页面切换*********************************/
	//表盘页面
	if(gTaskEnMark.UPDATE_DIAL_EN && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))	
	{
		modelListener->DialPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}
	//应用页面
	if(gTaskEnMark.UPDATE_APPPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace))
	{
		modelListener->AppPageChange(gFiveKeyFunc);
		gSwitchSpace = 0x0F;	//使能切换时间计数
	}

	/********************************更新各类信息*********************************/
	//更新时间信息,为使表盘页面滑动操作正常,在屏幕被点按时不更新数据
	if(gTaskEnMark.UPDATE_DIAL_EN && (gSystemTime.Seconds != gLastTimeSeconds)&&(gTaskStateBit.TouchPress == 0))	//每秒同步一次界面时间
	{
		modelListener->updateDate(gSystemDate.Year,gSystemDate.Month,gSystemDate.Date,gSystemDate.WeekDay);
		modelListener->updateTime(gSystemTime.Hours, gSystemTime.Minutes,
gSystemTime.Seconds);
		//更新新值
		gLastTimeSeconds = gSystemTime.Seconds;	
		//更新温度/步数/心率
		modelListener->updateTempStepHeart(gTemRH_Val.Tem,gSportStep,gHeartRate);
	}
#else //Designer仿真
		timeval timenow;
		gettimeofday(&timenow, NULL);
		//仿真更新时间
		modelListener->updateTime((timenow.tv_sec / 60 / 60) % 24,(timenow.tv_sec / 60) % 60,timenow.tv_sec % 60);
#endif	
}
/*********************gTaskEnMark赋值*************************/
//DialView的任务的状态
void Model::DialPageViewTask(bool enable)
{
	#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_DIAL_EN = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_DIAL_EN = 0;	//任务清除
#endif
}
//ApplicationPageView的任务的状态
void Model::ApplicationPageViewTask(bool enable)
{
	#if defined LINK_HARDWARE
	if(enable == true)	
		gTaskEnMark.UPDATE_APPPAGE = 1;	//任务使能
	else
		gTaskEnMark.UPDATE_APPPAGE = 0;	//任务清除
#endif
} 

Model.hpp中添加相关函数的说明。

#ifndef MODEL_HPP
#define MODEL_HPP

class ModelListener;

class Model
{
public:
    Model();
 void bind(ModelListener* listener)
    {
        modelListener = listener;
    }
    void tick();
		//DialPageView的任务的状态
		void DialPageViewTask(bool enable);
		//ApplicationPageView的任务的状态
		void ApplicationPageViewTask(bool enable);

protected:
    ModelListener* modelListener;
};

#endif // MODEL_HPP

ModelListener.hpp中添加相关虚函数。

 

#ifndef MODELLISTENER_HPP
#define MODELLISTENER_HPP

#include <gui/model/Model.hpp>
extern "C" {
#include "stdint.h"
}
class ModelListener
{
public:
    ModelListener() : model(0) {}
    
    virtual ~ModelListener() {}

    void bind(Model* m)
    {
        model = m;
    }
		//更新日期和时间
		virtual void updateDate(uint8_t Year, uint8_t Month, uint8_t Date, uint8_t WeekDay) {}
		virtual void updateTime(uint8_t Hours, uint8_t Minutes, uint8_t Seconds) {}
		//页面跳转
		virtual void DialPageChange(uint8_t newFiveKeyFunc){}
		virtual void AppPageChange(uint8_t newFiveKeyFunc){}
		//温度/步数/心率上传
		virtual void updateTempStepHeart(float newTem, unsigned long newStep, uint32_t newHeartRate){}
protected:
    Model* model;
};

#endif // MODELLISTENER_HPP

  点击魔术棒图标,在C/C++选项卡增加LINK_HARDWARE的宏定义,用于PC端仿真与硬件底层驱动的隔离。

打开DialPageView.cpp / DialPageView.hppDialPagePresenter.cpp/ DialPagePresenter.hpp文件,添加手表界面的信息上传代码。

DialPageView.cpp文件中添加数字表盘与模拟表盘的数据更新代码。

 

#include <gui/dialpage_screen/DialPageView.hpp>
#include <texts/TextKeysAndLanguages.hpp>
#include "BitmapDatabase.hpp"
//标准库
#include <stdio.h>
#include <string.h>
//
DialPageView::DialPageView()
{

}
//
void DialPageView::setupScreen()
{
    DialPageViewBase::setupScreen();
}
//
void DialPageView::tearDownScreen()
{
    DialPageViewBase::tearDownScreen();
}
//更新时间
void DialPageView::updateTime(uint8_t newHours, uint8_t newMinutes, uint8_t newSeconds)
{
		digitalClock.setTime24Hour(newHours, newMinutes, newSeconds);
		analogClock.setTime24Hour(newHours,newMinutes,newSeconds);
}
//更新日期
void DialPageView::updateDate(uint8_t newYear, uint8_t newMonth, uint8_t newDate, uint8_t newWeekDay)
{
		Unicode::snprintf(textSystemYearBuffer, TEXTSYSTEMYEAR_SIZE, "%04d", newYear + 2000);
    textSystemYear.invalidate();	
		//
		Unicode::snprintf(textSystemDateBuffer1, TEXTSYSTEMDATEBUFFER1_SIZE, "%02d", newMonth);
		Unicode::snprintf(textSystemDateBuffer2, TEXTSYSTEMDATEBUFFER2_SIZE, "%02d", newDate);
	  textSystemDate.invalidate();
		//
		Unicode::snprintf(textWeekDayBuffer, TEXTWEEKDAY_SIZE, "%d", newWeekDay);
    textWeekDay.invalidate();
		//
		Unicode::snprintf(DateWindowBuffer, DATEWINDOW_SIZE, "%02d", newDate);
    DateWindow.invalidate();	
		//
}
//进入APP页面或快速设置界面
void DialPageView::DialPageChange(uint8_t newFiveKeyFunc)
{
		handleKeyEvent(newFiveKeyFunc);
}
//更新温度、步数、心率数据
void DialPageView::updateTempStepHeart(float newTem, unsigned long newStep, uint32_t newHeartRate)
{
		//更新温度-数字表盘
		Unicode::snprintfFloat(textTempBuffer, TEXTTEMP_SIZE, "%.1f",newTem);
	  textTemp.invalidate();
		//更新温度-模拟表盘
		Unicode::snprintfFloat(textTemp_anBuffer, TEXTTEMP_AN_SIZE, "%.1f",newTem);
	  textTemp_an.invalidate();
		//更新步数-数字表盘
		Unicode::snprintf(textStepBuffer, TEXTSTEP_SIZE, "%d",newStep);
	  textStep.invalidate();
	//更新步数-模拟表盘
		Unicode::snprintf(textStep_anBuffer, TEXTSTEP_AN_SIZE, "%d",newStep);
	  textStep_an.invalidate();
		//更新脉搏-数字表盘
		Unicode::snprintf(textPulseBuffer, TEXTPULSE_SIZE, "%d",newHeartRate);
	  textPulse.invalidate();
		//更新脉搏-模拟表盘
		Unicode::snprintf(textPulse_anBuffer, TEXTPULSE_AN_SIZE, "%d",newHeartRate);
	  textPulse_an.invalidate();	
}

DialPageView.hpp文件中添加声明。

#ifndef DIALPAGEVIEW_HPP
#define DIALPAGEVIEW_HPP

#include <gui_generated/dialpage_screen/DialPageViewBase.hpp>
#include <gui/dialpage_screen/DialPagePresenter.hpp>

class DialPageView : public DialPageViewBase
{
public:
    DialPageView();
    virtual ~DialPageView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
		//更新日期和时间
		virtual void updateDate(uint8_t newYear, uint8_t newMonth, uint8_t newDate, uint8_t newWeekDay); 
		virtual void updateTime(uint8_t newHours, uint8_t newMinutes, uint8_t newSeconds);
		virtual void DialPageChange(uint8_t newFiveKeyFunc);
		//温度/步数/心率信息上传
		void updateTempStepHeart(float newTem, unsigned long newStep, uint32_t newHeartRate);
protected:
};

#endif // DIALPAGEVIEW_HPP

DialPagePresenter.cpp添加屏幕任务的使能与数据交互。

#include <gui/dialpage_screen/DialPageView.hpp>
#include <gui/dialpage_screen/DialPagePresenter.hpp>
//
DialPagePresenter::DialPagePresenter(DialPageView& v)
    : view(v)
{
}
//
void DialPagePresenter::activate()
{
	DialPagePresenterState(true);
}
//
void DialPagePresenter::deactivate()
{
	DialPagePresenterState(false);
}
//DialPagePresenter
void DialPagePresenter::DialPagePresenterState(bool enable)
{
	if(enable == true)
		model->DialPageViewTask(true);
	else
		model->DialPageViewTask(false);
}
//更新时间
void DialPagePresenter::updateTime(uint8_t newHours, uint8_t newMinutes, uint8_t newSeconds)
{
    view.updateTime(newHours, newMinutes, newSeconds);
}
//更新日期
void DialPagePresenter::updateDate(uint8_t newYear, uint8_t newMonth, uint8_t newDate, uint8_t newWeekDay)
{
    view.updateDate(newYear, newMonth, newDate, newWeekDay);
}
//五向按键切换页面
void DialPagePresenter::DialPageChange(uint8_t newFiveKeyFunc)
{
	  view.DialPageChange(newFiveKeyFunc);
}
//更新温度/步数/心率
void DialPagePresenter::updateTempStepHeart(float newTem, unsigned long newStep, uint32_t newHeartRate)
{
		view.updateTempStepHeart(newTem,newStep,newHeartRate);	
}

DialPagePresenter.hpp添加以下代码。

#ifndef DIALPAGEPRESENTER_HPP
#define DIALPAGEPRESENTER_HPP
#include <gui/model/ModelListener.hpp>
#include <mvp/Presenter.hpp>

using namespace touchgfx;

class DialPageView;

class DialPagePresenter : public touchgfx::Presenter, public ModelListener
{
public:
    DialPagePresenter(DialPageView& 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 ~DialPagePresenter() {};
		//DialPagePresenter的状态
		void DialPagePresenterState(bool enable);
		//更新日期和时间
		virtual void updateDate(uint8_t newYear, uint8_t newMonth, uint8_t newDate, uint8_t newWeekDay); 
		virtual void updateTime(uint8_t newHours, uint8_t newMinutes, uint8_t newSeconds);
		virtual void DialPageChange(uint8_t newFiveKeyFunc);
		//更新温度/步数/心率
		virtual void updateTempStepHeart(float newTem, unsigned long newStep, uint32_t newHeartRate);
private:
    DialPagePresenter();

    DialPageView& view;
};

#endif // DIALPAGEPRESENTER_HPP

 点击全编译,运行PC端的仿真,下载至开发板,进行代码的验证。

PC端的仿真结果。 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1326248.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【点选验证码识别】某招标网站反爬虫分析与验证码自动识别

文章目录 1. 写在前面2. 风控描述3. 验证码裁剪4. 验证码识别 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感兴趣…

Redis基础篇-002 初识Redis

1、认识NoSQL 1.1 概念 NoSQL是一个非关系型数据库。 常见的NoSQL有&#xff1a;Redis、MongoDB 1.2 NoSQL与SQL的区别 类别SQLNoSQL数据结构结构化非结构化数据关联关联非关联查询方式SQL非SQL事务特性ACIDBASE存储方式磁盘内存扩展性垂直水平使用场景1&#xff09;数据结…

Uniapp + Vue3 封装请求工具挂载全局

新建request.js工具类 const http {// baseUrl 地址baseUrl: http://localhost:8080,// 请求方法request(config) {// config&#xff1a;请求配置对象&#xff0c;具体参照uniapp文档config beforeRequest(config)// 请求地址拼接config.url this.baseUrl config.url// 异…

WIN10安装gurobi给matlab使用(记录)

https://www.gurobi.com/downloads/gurobi-software/ 这是以前的matlab路径&#xff0c;需要修改成新的 使用校园网激活一下 运行gurobi_setup Google报错信息&#xff0c;发现mathwork官方的解释是&#xff1a;找不到相关的dll文件&#xff0c;所以mex无效。 解决方案&…

Unity | Shader基础知识(第八集:案例<漫反射材质球>)

目录 一、本节介绍 1 上集回顾 2 本节介绍 二、什么是漫反射材质球 三、 漫反射进化史 1 三种算法结果的区别 2 具体算法 2.1 兰伯特逐顶点算法 a.本小节使用的unity自带结构体。 b.兰伯特逐顶点算法公式 c.代码实现——兰伯特逐顶点算法 2.2 代码实现——兰伯特逐…

Windows下结束进程

可以用命令 netstat -ano | findstr :8088 直接找到端口号为8088的进程PID&#xff1b; 根据PID进程号结束进程 &#xff1a;taskkill /pid 14696 -t -f ;

研发提效必备技能:手把手教你基于Docker搭建Maven私服仓库

沉淀&#xff0c;成长&#xff0c;突破&#xff0c;帮助他人&#xff0c;成就自我。 大家好&#xff0c;我是冰河~~ 在研发的过程中&#xff0c;很多企业都会针对自身业务特点来定制研发一些工具类库&#xff0c;但是这些工具类库又不会对外公开&#xff0c;那如何在组织内部共…

如何使用支付宝的沙箱环境在本地配置模拟支付并发布至公网测试

文章目录 前言1. 下载当面付demo2. 修改配置文件3. 打包成web服务4. 局域网测试5. 内网穿透6. 测试公网访问7. 配置二级子域名8. 测试使用固定二级子域名访问 前言 在沙箱环境调试支付SDK的时候&#xff0c;往往沙箱环境部署在本地&#xff0c;局限性大&#xff0c;在沙箱环境…

oracle23安装并 配置内网代理(安装nginx oracle23)

安装nginx步奏如下 1.安装所需依赖 yum install -y gcc gcc-c pcre pcre-devel zlib zlib-devel openssl openssl-devel automake autoconf libtool make2. 解压nginx压缩包&#xff0c;进入解压后的nginx目录 tar -xvf ./nginx-1.24.0.tar.gzcd ./nginx3. 以下编译命令中增…

深度学习或机器学习的模型部署相关的初步了解及分析

机器学习-深度学习 部署相关资料文档 这是上班之后的第一个文档&#xff0c;由于项目原因需要去了解一些和模型部署相关的知识&#xff0c;所以就简单了解了一下相应的部署引擎和框架&#xff0c;也是刚刚开始学习&#xff0c;如果有什么写的不对的欢迎大家交流&#xff0c;看…

2024年3月电子学会青少年编程等级考试时间安排

1考试方式 1. 在线居家考试&#xff08;全国&#xff09;&#xff1b; 2. 对于符合线下考试要求的考试服务网点&#xff0c;经地方实地调研报学会总部批准后&#xff0c;可组织线下考试。 2报名时间 报名时间&#xff1a;2023年12月21日-2024年3月12日16:00&#xff1b; 考…

Web API ------- requestAnimationFrame

官方文档 requestAnimationFrame 是什么 window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画&#xff0c;并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数&#xff0c;该回调函数会在浏览器下一次重绘之前执行 …

HTML输出特殊字符详细方法

以下是部分特殊字符代码表&#xff0c;它们的完整应用代码格式为&#xff1a;&#;用下面的四位数字替换&#xff0c;将得到对应的符号。&#xff08;注意&#xff1a;应用这些代码&#xff0c;编辑器应该切换到HTML模式&#xff09; ☏260f ☎260e ☺263a ☻263b ☼263c ☽…

【UML】第6篇 用例图(1/3)

目录 一、什么是用例图 二、参与者 2.1 什么是参与者 2.2 如何识别参与者 2.3 参与者之间的关系 从今天开始&#xff0c;就到了最干的各种的图的梳理和学习了&#xff0c;未来AI就能编码了&#xff0c;把业务建模和设计的基本功打好&#xff0c;也许能和AI和平相处呢。 一…

第三节TypeScript 基础类型

1、typescript的基础类型 如下表&#xff1a; 数据类型 关键字 描述 任意类型 any 生命any的变量可以赋值任意类型的值 数字类型 number 整数或分数 字符串类型 string 使用单引号&#xff08;‘’&#xff09;或者双引号&#xff08;“”&#xff09;来表示字符串…

nodejs微信小程序+python+PHP购物商城网站-计算机毕业设计推荐

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

3D模型格式转换工具如何实现高性能数据转换?请看CAE系统开发实例!

​ 客户背景 DP Technology是全球知名的CAM的供应商&#xff0c;在全球8个国家设有18个办事处。DP Technology提供的CAMESPRIT系统是一个用于数控编程&#xff0c;优化和仿真全方面的CAM系统。CAMESPRIT的客户来自多个行业&#xff0c;因此支持多种CAD工具和文件格式显得格外重…

区块链技术与应用 【全国职业院校技能大赛国赛题目解析】第一套区块链系统部署与运维

第一套区块链系统部署与运维题目 环境 : ubuntu20 fisco : 2.8.0 子任务1-2-1: 搭建区块链系统并验证 题意: 要求搭建一条四节点的区块链系统,我们选择使用fisco作为此次测试的链子 我们使用build_chain.sh进行构建单机四节点,并且使用官方的默认端口【正式比赛大概率不…

java使用面向对象实现图书管理系统

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

算法基础之筛质数

筛质数 核心思想&#xff1a;筛法求质数 埃氏筛法: 每次用 2 3 4…. p-1 筛 2 - p之间的数出现2 3 4 …的倍数时 去掉(4实际已经被去掉 不会用4去筛)当2~p-1的数都没有筛掉p 说明p是质数 优化: 只用2~p-1中质数筛 线性筛法: 核心: n只会被其最小质因子筛掉 每一个合数都只…