|
 |
| 목록으로 가기.. |
|
STM TouchGFX설계할때 main에서 View에 접근하는 순서 |
김종호
|
삭제하기
|
|
'TouchGFX는 이 문제를 해결하기 위해 Model::tick()이라는 함수를 제공합니다.
이 함수는 화면 주사율에 맞춰 1초에 약 60번씩 UI 스레드 내부에서 자동으로 실행됩니다.
따라서 main.c에서는 변수값만 바꿔두고, Model::tick()이 그 변수를 감시(Polling)하다가 값이 변하면 Presenter를 통해 View(화면)로 전달하는 방식을 사용해야 합니다.
이번에도 한 번에 복사하실 수 있도록 전체 구현 코드를 마크다운 블록으로 정리해 드립니다. (예: 센서 값을 읽어와서 화면의 텍스트를 업데이트하는 상황)'
### 1. C 언어 영역: 데이터 제공 (`main.c`)
하드웨어 값을 담을 변수와, 그 값을 반환해줄 Getter 함수를 만듭니다.
**`Core/Src/main.c`**
```c
/* USER CODE BEGIN 0 */
int hw_sensor_value = 0; // 하드웨어에서 업데이트할 변수
// C++ 영역(Model)에서 값을 읽어갈 수 있도록 제공하는 함수
int get_sensor_value(void)
{
return hw_sensor_value;
}
/* USER CODE END 0 */
```
---
### 2. Model 영역: 데이터 감시 및 전달 (`Model.hpp` / `Model.cpp`)
`Model::tick()`에서 1초에 60번씩 `get_sensor_value()`를 확인합니다.
**`gui/include/gui/model/Model.hpp`**
```cpp
#ifndef MODEL_HPP
#define MODEL_HPP
// 1. main.c에 있는 C 함수 선언
extern "C" {
int get_sensor_value(void);
}
class ModelListener;
class Model
{
public:
Model();
void bind(ModelListener* listener) { modelListener = listener; }
// 1초에 60번씩 자동 실행되는 함수
void tick();
protected:
ModelListener* modelListener;
// 이전 값을 기억해둘 변수 (값이 변했을 때만 업데이트하기 위함)
int last_sensor_value;
};
#endif // MODEL_HPP
```
**`gui/src/model/Model.cpp`**
```cpp
#include
#include
Model::Model() : modelListener(0), last_sensor_value(0)
{
}
void Model::tick()
{
// 매 프레임마다 하드웨어 값을 읽어옴
int current_value = get_sensor_value();
// 값이 이전과 달라졌을 때만 UI 업데이트 요청
if (current_value != last_sensor_value)
{
last_sensor_value = current_value;
// Listener(Presenter)가 연결되어 있다면 데이터 전달
if (modelListener != 0)
{
modelListener->sensorValueChanged(current_value);
}
}
}
```
---
### 3. ModelListener 영역: 인터페이스 정의 (`ModelListener.hpp`)
Model이 Presenter를 호출할 수 있도록 약속(가상 함수)을 정의합니다. **(이 부분을 놓치는 경우가 많으니 주의하세요!)**
**`gui/include/gui/model/ModelListener.hpp`**
```cpp
#ifndef MODELLISTENER_HPP
#define MODELLISTENER_HPP
#include
class ModelListener
{
public:
ModelListener() : model(0) {}
virtual ~ModelListener() {}
void bind(Model* m) { model = m; }
// Model에서 호출할 가상 함수 추가 (빈 괄호 {} 로 기본 구현 필수)
virtual void sensorValueChanged(int newValue) {}
protected:
Model* model;
};
#endif // MODELLISTENER_HPP
```
---
### 4. Presenter 영역: View로 중계 (`Presenter.hpp` / `Presenter.cpp`)
Model에서 올라온 데이터를 화면(View)으로 넘겨줍니다.
**`gui/include/gui/screen1_screen/Screen1Presenter.hpp`**
```cpp
// ... 기존 코드 생략 ...
class Screen1Presenter : public touchgfx::Presenter, public ModelListener
{
public:
// ... 기존 코드 ...
// ModelListener에 선언한 함수 오버라이딩
virtual void sensorValueChanged(int newValue);
};
```
**`gui/src/screen1_screen/Screen1Presenter.cpp`**
```cpp
// ... 기존 코드 생략 ...
// Model에서 값이 바뀌면 이 함수가 호출됨
void Screen1Presenter::sensorValueChanged(int newValue)
{
// View의 UI 갱신 함수 호출
view.updateSensorText(newValue);
}
```
---
### 5. View 영역: 최종 화면 갱신 (`View.hpp` / `View.cpp`)
화면에 있는 텍스트 위젯(예: `textArea1`)의 숫자를 바꿉니다.
**`gui/include/gui/screen1_screen/Screen1View.hpp`**
```cpp
// ... 기존 코드 생략 ...
class Screen1View : public Screen1ViewBase
{
public:
// ... 기존 코드 ...
// Presenter가 호출할 UI 업데이트 함수
void updateSensorText(int newValue);
};
```
**`gui/src/screen1_screen/Screen1View.cpp`**
```cpp
// ... 기존 코드 생략 ...
// Designer에서 설정한 Wildcard Buffer가 켜져 있어야 합니다.
void Screen1View::updateSensorText(int newValue)
{
// 정수를 텍스트 버퍼에 포맷팅 (Designer에서 Wildcard 설정 필수)
Unicode::snprintf(textArea1Buffer, TEXTAREA1_SIZE, "%d", newValue);
// 해당 텍스트 위젯을 다시 그리도록(Redraw) 요청
textArea1.invalidate();
}
```
|
| 
|