자습서 2: 나만의 애플리케이션 생성하기
자습서를 따라 진행하면서 TouchGFX의 기본 사항에 대해 자세히 알아보십시오. 이 자습서에서는 이미지를 애플리케이션에 추가하는 방법, 버튼을 사용하는 방법 및 텍스트와 계산된 숫자를 사용하는 방법을 알아볼 것입니다. 마지막 단계에서는 코드를 작성하여 TouchGFX Designer에서 생성한 UI를 보기 좋게 다듬어 볼 것입니다. 이 자습서는 TouchGFX에 대해서는 전혀 모르지만 프로그래밍에 대해서는 약간의 경험이 있는 사용자를 대상으로 합니다.
1단계: 배경 이미지 설정하기
첫 번째 단계에서는 PNG 이미지를 배경으로 삽입하는 방법에 대해 알아보겠습니다. 하지만, 그 전에 새 프로젝트를 생성하겠습니다.
새 프로젝트 시작하기
TouchGFX Designer에서 새 프로젝트를 시작합니다. 프로젝트 이름을 "MyApplication1"로 지정하겠습니다. 이 프로젝트는 "STM32F746G Discovery Kit"를 기반으로 합니다.
다른 STM32 평가 키트가 있다면 TouchGFX Designer에서 제공되는 목록을 살펴보고 해당 보드가 지원되는지 확인하십시오. 지원되는 보드가 없다면 "Simulator"를 선택하여 Windows 컴퓨터에서 애플리케이션을 실행하면 됩니다.
이 자습서는 해상도가 480x272인 디스플레이에서 실행됩니다. 해상도가 다른 애플리케이션 템플릿을 선택하면 그래픽이 화면에 맞지 않지만 자습서는 마칠 수 있을 것입니다.
빈 프로젝트를 새로 생성했으니, 이제 프로젝트를 수정해 보겠습니다.
TouchGFX 애플리케이션은 다수의 화면으로 구성되어 있습니다. 화면에는 사용자 인터페이스를 구성하는 여러 위젯이 포함되어 있습니다. 화면은 전체 디스플레이를 덮기 때문에 한 번에 하나의 화면만 사용자에게 표시됩니다.
가장 먼저 초기 스크린의 이름을 아래와 같이 "Main"으로 변경하겠습니다. 왼쪽 목록에서 Screen(1)을 선택한 후 오른쪽의 이름 필드(2)에서 이름을 변경합니다. 목록(1)에서 화면을 더블 클릭하거나 마우스 오른쪽 버튼으로 클릭하여 이름을 변경할 수도 있습니다.
배경 삽입하기
일반적으로 하나 이상의 위젯으로 화면의 전체 배경을 덮는 것이 좋습니다. 예를 들어 Box 또는 Image 위젯이 될 수 있습니다. 위젯으로 덮지 않으면 배경이 검은색으로 표시됩니다. 이 애플리케이션에서는 Image를 사용하겠습니다.
TouchGFX Designer에서 이미지를 사용하려면 먼저 파일을 가져와야 합니다. TouchGFX는 BMP 및 PNG 이미지를 지원합니다(TouchGFX Designer를 통해서는 PNG 이미지를 가져올 수만 있음). PNG 파일이 용량이 더 작고 투명 픽셀을 지원하므로 BMP 파일보다 선호도가 높습니다.
이 자습서에서 사용할 이미지는 이 링크에서 다운로드할 수 있습니다. 다운로드한 파일을 디스크의 디렉터리에 압축 해제합니다.
배경으로 사용할 파일의 이름을 "background.png"로 지정하겠습니다. 파일을 가져오는 방법은 다음과 같습니다.
- Images 탭을 선택하고 "+" 버튼을 클릭합니다.
- 압축을 해제한 폴더로 이동하여 "background.png" 파일을 선택합니다.
- Open을 눌러 가져옵니다.
또한 파일 탐색기에서 이미지를 이미지 탭으로 "드래그 앤 드롭"하거나 캔버스로 직접 드래그 앤 드롭하여 프로젝트에 가져올 수도 있습니다.
단, 프로젝트로 가져온 이미지는 변환되어 프로젝트에 컴파일되므로 플래시 공간을 차지하게 됩니다. 따라서 필요한 이미지만 가져와야 합니다. 왼쪽에서 "Images" 버튼(1)을 클릭한 후 오른쪽에서 "+" 버튼(2)을 클릭하여 이미지를 추가합니다. TouchGFX Designer에서 일반 파일 브라우저가 열립니다. 그러면 다운로드한 이미지로 이동하여 “background.png” 파일을 선택할 수 있습니다.
이제 애플리케이션에서 이미지를 사용할 준비를 마쳤습니다. 이미지를 사용하기 위해서는 Image 위젯이 필요합니다.
- 왼쪽에서 Canvas 버튼(1)을 클릭합니다.
- 위젯 목록에서 Image 위젯(2)을 찾습니다.
- Image 위젯을 클릭하여 화면에 삽입합니다.
위젯의 이름을 의미 있는 이름으로 변경하는 것이 좋습니다. 여기에서는 "backgroundImage"(3)로 변경하겠습니다.
위젯을 삽입한 후에는 일반적으로 위치 또는 색상과 같은 속성을 구성해야 합니다. 선택한 위젯의 속성은 TouchGFX Designer에서 오른쪽에 표시됩니다. 화면 내 위젯은 왼쪽에 트리 뷰 형식(1)으로 표시됩니다. 이 경우 점의 위치 0,0에도 만족하지만, 이전에 가져온 "background.png" 파일을 선택하도록 Image 속성을 변경하려고 합니다. Image 속성(2)을 클릭하고 "background.png"를 선택합니다.
이제 화면이 하나인 간단한 애플리케이션을 생성했습니다. 이 화면은 전체 사용자 인터페이스를 덮는 배경 이미지로만 구성되어 있습니다.
계속 진행하기 전에 "Run Simulator" 버튼을 눌러 프로젝트가 컴파일되고 실행되는지 확인하십시오. 아직 활성 위젯을 추가하지 않았으므로 애플리케이션과 인터랙션할 수는 없습니다.
2단계: 버튼 추가하기
이 단계에서는 버튼 2개를 애플리케이션에 추가한 후 다른 PNG 파일을 사용하여 커스터마이징하겠습니다.
버튼 추가하기
- Widgets 탭(1)에서 Button 위젯을 클릭하여 버튼을 화면에 추가합니다.
- 새 위젯을 마우스로 드래그하여 이동합니다.
- 위치를 변경할 버튼의 좌표는 x=40, y=60입니다. 오른쪽에 있는 속성(2)에서 위치를 확인합니다.
- 새로운 위젯의 이름을 "buttonUp"으로 지정합니다.
- x=40, y=150의 위치에 Button 위젯을 하나 더 추가합니다. 이 위젯의 이름을 "buttonDown"으로 지정합니다.
프로젝트가 이제 다음과 같이 표시됩니다.
X 및 Y 속성에서 작은 위/아래 버튼을 사용하여 위젯의 위치를 정밀하게 조정할 수 있습니다. 또한 캔버스에서 버튼 위젯을 클릭하여 선택한 후 키보드의 화살표 키를 사용하여 위치를 조정할 수도 있습니다.
형태 변경하기
이제 버튼의 형태를 바꿔보겠습니다. 하나의 버튼은 2개의 이미지로 구성됩니다. 하나는 버튼을 눌렀을 때 표시되는 이미지이고, 나머지 하나는 버튼을 누르지 않았을 때(손을 뗐을 때) 표시되는 이미지입니다. 대부분의 위젯은 미리 정의된 스타일 세트가 함께 제공됩니다. 이러한 스타일은 기본적으로 특정 형태를 설명하는 위젯의 특정 속성에 대한 값의 세트입니다. 이러한 스타일은 프로토타입을 빠르게 제작하는 데 적합하지만, 실제 애플리케이션을 생성할 때는 스타일을 변경하는 경우가 많습니다.
이전 단계와 같이 Images 탭으로 이동하여 오른쪽 상단 모퉁이에 있는 "+" 아이콘을 클릭하고 일부 이미지를 가져옵니다. 이번에는 4개의 이미지, "button_down_pressed.png", "button_down_released.png", "button_up_pressed.png", "button_up_released.png"를 가져오겠습니다.
5개의 이미지만 가져왔지만, 보시는 것처럼 프로젝트에는 총 7개의 이미지가 있습니다. 나머지 2개의 이미지는 기본적으로 버튼에 사용되는 파란색 이미지로, 더 이상 사용되지 않으면 자동으로 제거됩니다.
캔버스로 돌아가서 "buttonUp" 버튼을 선택합니다. "Released Image" 속성(1)을 클릭한 다음 "Project”(2)를 클릭한 후, 마지막으로 올바른 이미지(3)를 선택합니다. "buttonUp"의 경우 Released Image 속성에서 "button_up_released.png"를 선택합니다. Pressed Image에서는 "button_up_pressed.png"를 선택합니다.
TouchGFX Designer의 캔버스에서 버튼의 형태를 바로 확인할 수 있습니다.
"buttonDown"의 경우에는 Released Image에서 "button_down_released.png"를 선택하고 Pressed Image에서는 "button_down_pressed.png"를 선택합니다.
이제 버튼 설정을 마쳤습니다. "Run Simulator"를 클릭하여 애플리케이션을 실행해 봅니다.
2개의 버튼을 눌러 보고 버튼이 올바르게 구성되었는지 확인합니다.
Tip
3단계: 텍스트 추가하기
이 단계에서는 대형 TextArea 위젯을 애플리케이션에 추가하겠습니다.
모든 텍스트는 TextArea 위젯을 사용하여 표시되지만, 여기에서는 TextArea를 애플리케이션에 추가하기 전에 먼저 이미지를 하나 더 추가하여 텍스트 배경을 멋지게 바꿔보겠습니다.
텍스트 배경
- 다른 이미지 파일인 "counter_box.png"를 가져옵니다.
- 새로운 Image 위젯을 삽입합니다.
- 이름을 "textBackground"로 지정합니다.
- 위치 좌표를 x=250, y=59로 지정합니다.
- Image 속성을 "counter_box"로 설정합니다.
텍스트 추가하기
이제 TextArea 위젯을 추가할 준비가 되었습니다. Widgets/Miscellaneous 드롭다운 메뉴에서 TextArea 아이콘을 클릭합니다. 위젯의 이름을 "textCounter"로 변경한 후 위젯을 x=250, y=90 위치로 옮깁니다. 위젯에 큰 텍스트를 표시하려고 합니다. 따라서 Auto-size 속성을 선택 해제하고 크기를 고정 너비 W=152로, 고정 높이 H=90으로 설정합니다.
TextArea 위젯의 기본 색상은 검은색으로, 배경에서는 다소 어둡게 보입니다. "textCounter"에서 Color 속성을 선택한 후 색상을 흰색으로 변경합니다.
텍스트 타이포그래피 변경하기
텍스트를 더 크게 조정하려고 합니다. 텍스트의 크기를 더 크게 조정하는 방법은 텍스트에 사용된 Typography를 변경하는 것입니다. 타이포그래피는 텍스트의 Font(예: Verdana), Size 및 Alignment(왼쪽, 오른쪽 또는 중앙)를 정의합니다.
TouchGFX Designer에서 왼쪽 상단에 있는 Texts 탭(1)을 선택하고, Typographies(2)를 클릭한 다음, "Default" 타이포그래피의 크기를 80(3)으로 업데이트합니다.
왼쪽 상단에 있는 "Canvas" 탭을 클릭하여 Screen으로 돌아가면 이제 텍스트가 더 크게 보입니다. 실제로는 전체 텍스트인 "New Text"를 읽을 수도 없습니다. Alignment 속성 아래의 중앙 아이콘을 클릭하여 텍스트를 중앙에 배치(1)합니다.
와일드카드 텍스트 사용하기
TextArea에 버튼으로 변경할 수 있는 숫자를 표시하려고 합니다. 이를 위해서는 "와일드카드"를 포함하도록 텍스트를 변경해야 합니다. 와일드카드는 런타임 시 숫자와 같은 다른 것으로 대체할 수 있는 텍스트의 마커("<d>")입니다. 여기서는 숫자만 표시하려고 하므로 텍스트를 "<d>"로만 변경하겠습니다. 다른 프로젝트에서는 동적인 부분을 고정 텍스트와 결합할 수 있습니다(예: "Temperature: <temp> °C").
Note
텍스트를 "<d>"(1)로 변경하고, "Wildcard 1"(2)을 클릭하고, 기본값을 "0"으로 설정한 후 "Use wildcard buffer"를 선택합니다.
"Run Simulator"를 클릭하여 애플리케이션을 실행해 봅니다.
Further reading
4단계: 코드 추가하기
TouchGFX Designer에서는 인터랙션을 통해 액션을 버튼에 쉽게 연결할 수 있습니다. 인터랙션은 트리거(예: 버튼 누름)를 액션(예: 코드 실행, 요소 이동)에 연결합니다.
오른쪽 상단 모퉁이에 있는 Interactions 탭(1)을 선택하고 "+" 버튼을 클릭하여 새 인터랙션을 생성합니다.
각 버튼에 대해 하나씩 2개의 인터랙션을 생성하겠습니다. 그런 다음 현재 화면에서 C++ 메소드를 호출하도록 두 인터랙션을 설정하겠습니다.
- Trigger 속성을 "Button is clicked"로 변경합니다.
- Choose clicked source 속성을 "buttonUp"으로 설정합니다.
- Action 속성을 "Call new virtual function"으로 변경합니다.
- Function Name으로 "buttonUpClicked"를 입력합니다.
- 또한 나중에 쉽게 알아볼 수 있도록 인터랙션에 의미 있는 이름을 지정해야 합니다.
"buttonDown"을 "clicked source"로 설정하여 다음과 같이 비슷한 인터랙션을 생성합니다.
- "+"를 클릭하여 새 인터랙션을 시작합니다.
- Trigger 속성을 "Button is clicked"로 변경합니다.
- Choose clicked source 속성을 "buttonDown"으로 설정합니다.
- Action 속성을 "Call new virtual function"으로 변경합니다.
- Function Name으로 "buttonDownClicked"를 입력합니다.
- 또한 나중에 쉽게 알아볼 수 있도록 인터랙션에 의미 있는 이름을 지정해야 합니다.
"Generate Code" 버튼 또는 "Run Simulator" 버튼을 클릭하면 TouchGFX Designer가 생성된 코드를 방금 생성한 인터랙션에 입력한 정보로 업데이트합니다. 즉, 이 화면의 view 기본 클래스에 두 개의 새로운 가상 함수가 생성됩니다.
이에 대해 더 자세히 살펴보고 코드가 어떻게 실행되는지 알아보겠습니다. 오른쪽 하단에서 "Generate Code"를 클릭한 후 왼쪽 하단에 있는 "Files" 버튼을 클릭합니다. 그러면 애플리케이션 폴더에 파일 탐색기가 나타납니다. 다음 폴더로 이동합니다.
MyApplication1/TouchGFX/generated/gui_generated/include/gui_generated/main_screen/
그런 다음 MainViewBase.hpp
파일을 엽니다. 원한다면 프로젝트 파일 중 하나를 열고 IDE에서 파일을 찾을 수도 있습니다.
IDE | 프로젝트 파일 경로 |
---|---|
STM32CubeIDE | MyApplication1/STM32CubeIDE/.project |
Visual Studio | MyApplication1/TouchGFX/simulator/msvs/Application.sln |
IAR Embedded Workbench 8 | MyApplication1/EWARM/Project.eww |
KEIL μVision v5 | MyApplication1/MDK-ARM/STM32F746G_DISCO.uvprojx |
Note
새로운 가상 메소드는 MainViewBase
클래스의 public 부분에 있습니다. 생성한 메소드에는 구현체가 비어 있습니다. 이유는 프로그래머가 MainView
하위클래스에서 이러한 메소드를 구현해야 하기 때문입니다.
MainViewBase.hpp
/*********************************************************************************/
/********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
/*********************************************************************************/
#ifndef MAINVIEWBASE_HPP
#define MAINVIEWBASE_HPP
#include <gui/common/FrontendApplication.hpp>
#include <mvp/View.hpp>
#include <gui/main_screen/MainPresenter.hpp>
#include <touchgfx/widgets/Image.hpp>
#include <touchgfx/widgets/Button.hpp>
#include <touchgfx/widgets/TextAreaWithWildcard.hpp>
class MainViewBase : public touchgfx::View<MainPresenter>
{
public:
MainViewBase();
virtual ~MainViewBase() {}
virtual void setupScreen();
/*
* Custom Action Handlers
*/
virtual void buttonUpClicked()
{
// Override and implement this function in MainView
}
virtual void buttonDownClicked()
{
// Override and implement this function in MainView
}
...
가상 메소드 구현하기
이제 남은 작업은 사용자가 버튼을 누를 때 카운터 값이 바뀌도록 두 메소드를 구현하는 것입니다. 이를 위해 MainView
클래스에서 두 메소드를 다시 선언합니다. 이 클래스는 아래 파일에서 찾을 수 있습니다.
MyApplication1/TouchGFX/gui/include/gui/main_screen/MainView.hpp
이 파일을 열고 다음과 같이 두 함수 선언을 클래스에 삽입합니다.
MainView.hpp
#ifndef MAIN_VIEW_HPP
#define MAIN_VIEW_HPP
#include <gui_generated/main_screen/MainViewBase.hpp>
#include <gui/main_screen/MainPresenter.hpp>
class MainView : public MainViewBase
{
public:
MainView();
virtual ~MainView() {}
virtual void setupScreen();
virtual void tearDownScreen();
virtual void buttonUpClicked();
virtual void buttonDownClicked();
}
다음 작업은 구현체를 .cpp 파일에 추가하여 두 메소드를 구현하는 것입니다. 이 파일의 위치는 다음과 같습니다.
MyApplication1/gui/src/main_screen/MainView.cpp
아래 구현체에서 touchgfx_printf
에 호출을 추가했습니다. 이 함수는 시뮬레이터를 실행할 때 텍스트의 줄을 출력하는 데 유용합니다. 이 함수를 사용하려면 utils.hpp를 포함해야 합니다. 타겟에서 실행해도 줄은 아무런 영향을 미치지 않습니다.
MainView.cpp
#include <gui/main_screen/MainView.hpp>
#include <touchgfx/utils.hpp>
MainView::MainView()
{
}
void MainView::setupScreen()
{
MainViewBase::setupScreen();
}
void MainView::tearDownScreen()
{
MainViewBase::tearDownScreen();
}
void MainView::buttonUpClicked()
{
touchgfx_printf("buttonUpClicked\n");
}
void MainView::buttonDownClicked()
{
touchgfx_printf("buttonDownClicked\n");
}
TouchGFX Designer에서 "Run Simulator"를 다시 클릭하여 새로운 코드를 실행합니다. 버튼을 여러 차례 클릭하여 인터랙션과 메소드가 정상적으로 작동하는지 확인합니다.
카운터 값 업데이트하기
마지막 작업은 사용자가 버튼을 누를 때 카운터 값이 업데이트되도록 새 메소드에서 C++ 코드를 작성하는 것입니다. 이를 위해 먼저 새로운 정수 변수인 counter
를 MainView
클래스에 추가합니다.
MainView.hpp
#ifndef MAIN_VIEW_HPP
#define MAIN_VIEW_HPP
#include <gui_generated/main_screen/MainViewBase.hpp>
#include <gui/main_screen/MainPresenter.hpp>
class MainView : public MainViewBase
{
public:
MainView();
virtual ~MainView() {}
virtual void setupScreen();
virtual void tearDownScreen();
virtual void buttonUpClicked();
virtual void buttonDownClicked();
protected:
int counter;
}
buttonUpClicked
메소드에서 카운터 값을 높입니다. 그러면 새 값이 문자열로 변환되어 이전 단계에서 TextArea에 구성한 와일드카드 버퍼로 복사됩니다.
MainView.cpp
#include <gui/main_screen/MainView.hpp>
MainView::MainView()
{
}
void MainView::setupScreen()
{
MainViewBase::setupScreen();
}
void MainView::tearDownScreen()
{
MainViewBase::tearDownScreen();
}
void MainView::buttonUpClicked()
{
touchgfx_printf("buttonUpClicked\n");
counter++;
Unicode::snprintf(textCounterBuffer, TEXTCOUNTER_SIZE, "%d", counter);
// Invalidate text area, which will result in it being redrawn in next tick.
textCounter.invalidate();
}
void MainView::buttonDownClicked()
{
touchgfx_printf("buttonDownClicked\n");
counter--;
Unicode::snprintf(textCounterBuffer, TEXTCOUNTER_SIZE, "%d", counter);
// Invalidate text area, which will result in it being redrawn in next tick.
textCounter.invalidate();
}
TextArea 위젯은 유니코드를 사용하므로 유니코드 버퍼에 쓰기를 지원하는 특수 printf 함수를 사용해야 합니다.
업데이트 후 textCounter
위젯에서 invalidate()
를 호출합니다. 이렇게 하면 카운터 값이 업데이트된 후 TextArea를 다시 그릴 수 있습니다.
애플리케이션을 완료하기 전에 한 가지 작업을 더 수행해야 합니다. TouchGFX는 필요한 문자만 포함하므로 "Default" 타이포그래피에 0~9 문자를 포함하도록 TouchGFX Designer에 지시해야 합니다. 이렇게 하려면, TouchGFX Designer로 돌아가서 "Texts" 탭과 "Typographies" 탭을 차례대로 클릭합니다. Default 타이포그래피의 "Wildcard Ranges" 열(1)에 범위 "0-9"를 추가합니다.
이제 "Run Simulator"를 다시 클릭하고 위로 버튼을 여러 차례 클릭합니다.
프로그램은 현재를 기준으로 하기 때문에 음의 수는 올바르게 처리하지 못합니다. 이 문제는 buttonDownClicked()
함수에 guard를 삽입하여 카운터가 0 밑으로 떨어지지 않도록 하거나 사용된 타이포그래피에 "-" 문자를 추가하여 해결할 수 있습니다. Default 타이포그래피의 Wildcard Characters 셀에 마이너스("-") 문자를 추가하기만 하면 됩니다.
이것으로 자습서 2를 마치겠습니다.