LVGL 시뮬레이터에서 내가 만든 UI 코드 실행하기
LVGL PC 시뮬레이터가 제공하는 기본 화면(lv_demo_widgets())은 기능은 충분하지만, 실제 프로젝트를 빠르게 익히기엔 기본 설정이 과하게 느껴질 수 있다. 그래서 src/main.c 안에서 데모를 주석 처리하고, 내가 만든 위젯을 직접 추가하여 LVGL을 학습하기 쉽게 하였다.
1. Custom widget을 추가한 이유?
기존 데모는 처음 LVGL을 배우는 사람에게 좀 과하고, 분석하고 테스트해보기 쉽지는 않아보인다. 기본 샘플을 미리 테스트해보기 위해 기존 UI를 비활성화하고, 기본 코드를 렌더링하는 커스텀 위젯을 추가하였다.
2. 커스텀 위젯 추가 방법
src/main.c에 아래와 같이 create_custom_ui() 함수를 추가한다. 그리고 기존 위젯을 보여주는 코드인 lv_demo_widgets()를 주석 처리한다.
그럼 내가 추가한 위젯이 시뮬레이터에서 보인다.
렌더링해보고 싶은 코드를 커스텀 위젯 함수 안에 넣고, 빌드해서 실행해보면 된다.
3. 기본 샘플 코드 설명
다음 함수는 lv_scr_load로 새 스크린을 만들고, 가운데 정렬된 패널 안에 텍스트, 진행률 표시, 슬라이더, 버튼을 넣는다. 그리고 각 요소에 여백과 너비를 지정한다.
/* src/main.c */
static void create_custom_ui(void)
{
lv_obj_t *scr = lv_obj_create(NULL);
lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE);
lv_scr_load(scr);
lv_obj_t *panel = lv_obj_create(scr);
lv_obj_set_size(panel, 360, 240);
lv_obj_align(panel, LV_ALIGN_CENTER, 0, 0);
lv_obj_set_style_radius(panel, 18, 0);
lv_obj_set_style_pad_all(panel, 16, 0);
lv_obj_t *title = lv_label_create(panel);
lv_label_set_text(title, "My Custom Widget");
lv_obj_set_style_text_font(title, &lv_font_montserrat_20, 0);
lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 0);
lv_obj_t *status = lv_label_create(panel);
lv_label_set_text(status, "Default UI ready");
lv_obj_align_to(status, title, LV_ALIGN_OUT_BOTTOM_MID, 0, 6);
lv_obj_t *bar = lv_bar_create(panel);
lv_obj_set_width(bar, 280);
lv_bar_set_value(bar, 64, LV_ANIM_OFF);
lv_obj_align_to(bar, status, LV_ALIGN_OUT_BOTTOM_MID, 0, 18);
lv_obj_set_style_radius(bar, 8, LV_PART_MAIN);
lv_obj_set_style_pad_row(bar, 12, LV_PART_MAIN);
lv_obj_t *slider = lv_slider_create(panel);
lv_slider_set_value(slider, 30, LV_ANIM_OFF);
lv_obj_set_width(slider, 280);
lv_obj_align_to(slider, bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 24);
lv_obj_t *btn = lv_btn_create(panel);
lv_obj_set_size(btn, 140, 50);
lv_obj_align(btn, LV_ALIGN_BOTTOM_MID, 0, -8);
lv_obj_t *btn_label = lv_label_create(btn);
lv_label_set_text(btn_label, "Run Action");
}
main()에서 기존 lv_demo_widgets() 호출을 주석 처리하고 create_custom_ui()를 호출하면, 위 함수가 맨 처음 로딩되는 화면이 된다. 이렇게 직접 만든 패널에 새 위젯을 추가하거나 현재 요소를 수정하며 즉시 결과를 확인하는 흐름이 가능하다.
4. 실행 화면

5. 전체 코드 diff
전체 코드 변경 사항은 아래와 같다. 참고하실 분은 참고하세요.
diff --git a/src/main.c b/src/main.c
index c893220..c192c34 100644
--- a/src/main.c
+++ b/src/main.c
@@ -26,6 +26,8 @@
#include "hal/hal.h"
+static void create_custom_ui(void);
+
/*********************
* DEFINES
*********************/
@@ -69,14 +71,15 @@ int main(int argc, char **argv)
/* - lv_demo_stress(); */
/* - lv_example_label_1(); */
/* - etc. */
- lv_demo_widgets();
+ /* lv_demo_widgets(); */
+ create_custom_ui();
while(1) {
/* Periodically call the lv_task handler.
* It could be done in a timer interrupt or an OS task too.*/
uint32_t sleep_time_ms = lv_timer_handler();
if(sleep_time_ms == LV_NO_TIMER_READY){
- sleep_time_ms = LV_DEF_REFR_PERIOD;
+ sleep_time_ms = LV_DEF_REFR_PERIOD;
}
#ifdef _MSC_VER
Sleep(sleep_time_ms);
@@ -88,10 +91,49 @@ int main(int argc, char **argv)
return 0;
}
+static void create_custom_ui(void)
+{
+ lv_obj_t *scr = lv_obj_create(NULL);
+ lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE);
+ lv_scr_load(scr);
+
+ lv_obj_t *panel = lv_obj_create(scr);
+ lv_obj_set_size(panel, 360, 240);
+ lv_obj_align(panel, LV_ALIGN_CENTER, 0, 0);
+ lv_obj_set_style_radius(panel, 18, 0);
+ lv_obj_set_style_pad_all(panel, 16, 0);
+
+ lv_obj_t *title = lv_label_create(panel);
+ lv_label_set_text(title, "My Custom Widget");
+ lv_obj_set_style_text_font(title, &lv_font_montserrat_20, 0);
+ lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 0);
+
+ lv_obj_t *status = lv_label_create(panel);
+ lv_label_set_text(status, "Default UI ready");
+ lv_obj_align_to(status, title, LV_ALIGN_OUT_BOTTOM_MID, 0, 6);
+
+ lv_obj_t *bar = lv_bar_create(panel);
+ lv_obj_set_width(bar, 280);
+ lv_bar_set_value(bar, 64, LV_ANIM_OFF);
+ lv_obj_align_to(bar, status, LV_ALIGN_OUT_BOTTOM_MID, 0, 18);
+ lv_obj_set_style_radius(bar, 8, LV_PART_MAIN);
+ lv_obj_set_style_pad_row(bar, 12, LV_PART_MAIN);
+
+ lv_obj_t *slider = lv_slider_create(panel);
+ lv_slider_set_value(slider, 30, LV_ANIM_OFF);
+ lv_obj_set_width(slider, 280);
+ lv_obj_align_to(slider, bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 24);
+
+ lv_obj_t *btn = lv_btn_create(panel);
+ lv_obj_set_size(btn, 140, 50);
+ lv_obj_align(btn, LV_ALIGN_BOTTOM_MID, 0, -8);
+ lv_obj_t *btn_label = lv_label_create(btn);
+ lv_label_set_text(btn_label, "Run Action");
+}
#endif