教程2:建立您自己的應用程式
請跟隨本教程學習更多TouchGFX的基本知識。 您將學習如何將圖像新增到應用程式,以及如何使用按鈕。 您還將學習如何使用文字和計算數字。 在最後的步驟中,您將編寫程式碼,強化使用TouchGFX Designer建立的UI視覺效果。 本教程假設您沒有TouchGFX的相關知識,但是有一點程式設計的經驗。
第1步:設定背景圖像
在第一個步驟中,您將看到如何插入PNG圖像作為背景。 但首先我們將建立一個新專案。
啟動新專案
在TouchGFX Designer中啟動新專案。 我們將此專案命名為「MyApplication1」。 此專案是以「STM32F746G探索套件」為基礎。
如果您有其他STM32評估套件,請查看TouchGFX Designer提供的支援裝置清單中是否包含此套件。 如果您沒有支援的開發板,可以選擇「模擬器」,並直接在Windows電腦上執行應用程式。
請注意,本教程在解析度為480x272的顯示器上運作。 如果您選擇具有其他解析度的應用程式範本,則圖形與螢幕將不相符,儘管如此,您仍應能夠完成本教程。
現在有一個新建立的空白專案,我們要開始進行修改。
TouchGFX應用程式包含許多畫面。 畫面中包含許多小工具,這些小工具組成了使用者介面。 畫面包含整個顯示畫面,因此一次只能向使用者顯示一個畫面。
首先要做的是將初始畫面的名稱修改為「Main」,如下圖所示。 在左側清單中選擇畫面(1),並在右側的名稱欄位中修改名稱(2)。 也可對清單的畫面(1)按兩下或按右鍵來重新命名畫面。
插入背景
用一個或多個小工具覆蓋畫面的整個背景通常是個不錯的選擇。 例如,可以使用方塊或圖像。 如果不覆蓋,背景將顯示為黑色。 在此應用程式中,我們將使用圖像。
我們需要匯入檔案,才能在TouchGFX Designer中使用圖像。 TouchGFX支援BMP和PNG圖像(儘管TouchGFX Designer只支援匯入PNG圖像)。 PNG檔比BMP檔更好,因為前者更小且支援透明像素。
本教程使用的圖像可從此連結下載。 將檔案解壓縮到硬碟上的目錄。
我們想要使用名為「background.png」的檔案當作背景。 若要匯入該檔案:
- 選擇「圖像」分頁並點擊「+」按鈕。
- 瀏覽至解壓縮檔案夾,並選擇「background.png」檔案。
- 按下「開啟」以匯入檔案。
您也可以將檔案總管中的圖像拖放到「圖像」分頁上,甚至直接拖放到畫布上,即可將檔案匯入專案,
請注意,匯入專案的圖像將會經過轉換並編譯至專案中,因此會佔用快閃記憶體空間。 請只匯入需使用的圖像。 點擊左側的「圖像」按鈕(1),然後點擊右側的「+」按鈕(2),即可新增圖像。 TouchGFX Designer會開啟一般的檔案瀏覽器,您可以在這裡瀏覽下載的圖像,並選擇「background.png」檔案。
現在,我們可以在應用程式中使用此圖像。 為此,我們需使用圖像小工具。
- 點擊左側的「畫布」按鈕(1)
- 在小工具清單(2)中找到圖像小工具
- 點擊它,即可在畫面上插入圖像小工具。
建議將小工具名稱變更為有意義的名稱。 在本例中,我們將名稱變更為「backgroundImage」(3)。
在插入小工具後,通常需要設定一些相關屬性,如位置或顏色。 在TouchGFX Designer中,所選小工具的屬性會顯示在右側。 畫面中的小工具會顯示在左側的樹狀檢視中(1)。 在本例中,我們很滿意點0,0的所在位置,但想要變更圖像屬性,以便選擇之前匯入的檔案「background.png」。 點擊圖像屬性(2)並選擇「background.png」。
現在,我們已經建立了一個具有一個畫面的簡單應用程式,這個畫面含有一張已覆蓋整個使用者介面的背景圖像。
在繼續操作前,嘗試按下「執行模擬器」按鈕,以便確認專案正常編譯和執行。 由於尚未新增任何使用中的小工具,因此現在還不能與應用程式互動。
第2步:新增按鈕
在這一步中,我們將為應用增加兩個按鈕,並用不同的PNG檔為它們設定自訂外觀。
新增按鈕
- 要將按鈕新增到畫面,點擊「小工具」分頁(1)上的「按鈕」小工具。
- 用滑鼠拖曳新的小工具來移動它。
- 將按鈕定位在位置 (x=40, y=60) 處。 檢查右側屬性中的位置(2)。
- 將新的小工具命名為「buttonUp」。
- 在位置 (x=40, y=150) 處增加另一個按鈕。 將此小工具命名為「buttonDown」。
現在,專案如下圖所示:
您可以使用X和Y屬性的向上/向下小按鈕對小工具的位置進行微調。 您也可以選擇按鈕小工具(在畫布上點擊它),然後用鍵盤上的方向鍵調整位置。
變更外觀
現在,我們將變更按鈕的外觀。 按鈕是由兩幅圖像構成。 一幅圖像會在按鈕按下時顯示,另一幅圖像則在按鈕未按下(鬆開)時顯示。 大多數小工具都附帶一組預定義樣式,基本上是描述小工具實際外觀的一組特定屬性值。 這些樣式有助於進行快速的原型設計,但在建立實際應用時,通常會將它們替換掉。
與上一步相同,前往「圖像」分頁,並點擊右上角的「+」圖示匯入一些圖像。 這次匯入四張圖像:「button_down_pressed.png」、「button_down_released.png」、「button_up_pressed.png」和「button_up_released.png」。
你可以看到,雖然我們只匯入了5張圖像,但專案中共有7張圖像。 另外2張是按鈕上預設使用的藍色圖像。 當這些圖像不再使用時,系統會自動將其移除。
回到畫布並選擇「buttonUp」按鈕。 點擊「已釋放圖像」屬性(1),然後點擊「專案」顯示圖像(2),最後選擇正確的圖像(3)。 對於「buttonUp」,針對「已釋放圖像」屬性選擇「button_up_released.png」。 針對「已按下圖像」選擇「button_up_pressed.png」。
您可以立即看到TouchGFX Designer中畫布上按鈕的外觀。
對於「buttonDown」,針對「已鬆開圖像」選擇「button_down_released.png」,針對「已按下圖像」選擇「button_down_pressed.png」。
現在,您已完成按鈕的設定。 點擊「執行模擬器」試用您的應用程式。
嘗試使用兩個按鈕,以確認按鈕設定正確。
Tip
第3步:新增文字
在這一步中,我們將為應用新增一個大型TextArea小工具。
所有文字均透過TextArea小工具來顯示,但在將TextArea新增到應用之前,我們先新增另一張圖像,以便為文字提供更好的背景。
文字背景
- 匯入另一個影像檔「counter_box.png」。
- 插入新的圖像小工具
- 將其命名為「textBackground」
- 將其定位在 (x=250, y=59) 處。
- 將圖像屬性設定為「counter_box」。
新增文字
現在,我們可以新增TextArea小工具。 點擊「小工具/其他」下拉式功能表中的TextArea圖示。 將小工具重新命名為「textCounter」,並將小工具移動到位置 (x=250, y=90) 處。 我們要讓小工具顯示大文字,因此取消勾選自動調整大小屬性,並將尺寸設定為固定寬度=152,高度=90。
TextArea小工具的預設色彩是黑色,在我們使用的背景上顯得很暗。 選擇「textCounter」的色彩屬性,將顏色變更為白色。
變更文字字體排印
我們要讓文字更大。 為此,需變更文字使用的字體排印。 字體排印定義了文字的字型(如Verdana)、大小和對齊(置左、置右或置中)。
選擇TouchGFX Designer左上角的「文字」分頁(1),點擊「字體排印」(2),並將「預設」字體排印的大小更新為80 (3)。
回到螢幕 (點擊左上角的「畫布」分頁),現在我們可以看到文字大了許多。 事實上,我們無法讀取完整的文字「新增文字」。 點擊對齊屬性下的置中圖示,讓文字置中對齊 (1)。
使用萬用字元文字
我們要讓TextArea顯示可以用按鈕變更的數字。 為此,我們必須變更文字,以便包含「萬用字元」。 萬用字元是文字中的一種標記(「<d>」),在執行階段可以使用其他字元 (如數字) 代替。 我們只想顯示一個數字,因此將文字變更為「<d>」就好。 在其他專案中,您可以將動態部分與固定文字搭配使用,如「溫度:<temp>°C」。
Note
將文字修改為「<d>」(1),點擊「萬用字元1」(2),將預設值設定為「0」,並勾選「使用萬用字元緩衝區」。
點擊「執行模擬器」試用您的應用程式。
Further reading
第4步:新增程式碼
使用TouchGFX Designer時,可輕鬆地透過互動將動作連結到按鈕。 互動會將觸發條件(如按鈕按下)連結到動作(如執行程式碼或移動元素)。
選擇右上角的「互動」分頁(1),點擊「+」按鈕建立新互動。
我們將建立兩個互動,每個按鈕一個。 我們將兩個互動都設定用來在目前螢幕上呼叫C++方法。
- 將觸發條件屬性變更為「Button is clicked」。
- 將選擇已點擊來源屬性設定為「buttonUp」。
- 將動作屬性變更為「Call new virtual function」。
- 在函數名稱欄位輸入「buttonUpClicked」。
- 您也應為互動提供描述性名稱,以利日後識別。
用「buttonDown」建立相似互動「clicked source」:
- 點擊「+」開始新的互動。
- 將觸發條件屬性變更為「Button is clicked」。
- 將選擇已點擊的來源屬性設定為「buttonDown」。
- 將動作屬性變更為「Call new virtual function」。
- 在函數名稱處輸入「buttonDownClicked」。
- 您也應為互動提供描述性名稱,以利日後識別。
如果您點擊「產生程式碼」按鈕或「執行模擬器」按鈕,TouchGFX Designer將用您在剛建立的互動中輸入的資訊更新產生的程式碼。 這表示它將在「檢視」基底類別中為此螢幕建立兩個新的虛擬函數。
我們進一步研究要如何執行自己的程式碼。 點擊右下角的「產生程式碼」按鈕,然後點擊左下角的「檔案」按鈕。 此動作會使檔案總管置於應用程式資料夾。 瀏覽至以下資料夾:
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
類別的公開部分。 產生的方法具有空實作。 用意是程式設計師在會子類別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中再次點擊「執行模擬器」來執行新程式碼。 多次點擊按鈕,確認互動和方法的運作符合預期:
更新計數器值
最後一個任務是在新方法中寫入C++程式碼,以便在使用者按下按鈕時更新計數器值。 為此,我們首先在MainView
類別中新增整數變數counter
:
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小工具使用Unicode,因此我們必須使用支援寫入Unicode緩衝區的特殊snprintf函數。
請注意,我們會在更新後在textCounter
小工具上呼叫 invalidate()
。 如此可確保在計數器值更新後重繪TextArea。
在應用完成前,還有一件事要做。 TouchGFX只包含需要的字元,因此需告知TouchGFX Designer在「預設」字體排印中包含字元0-9。 為此,返回TouchGFX Designer並點擊「文字」分頁,然後點擊「字體排印」分頁。 在「預設」字體排印的「萬用字元範圍」欄位中新增範圍「0-9」(1)。
現在,再次點擊「執行模擬器」,然後點擊幾次「向上」按鈕:
程式現在還不能正確處理負數。 為了解決這個問題,可在buttonDownClicked()
函數中插入guard,以確保計數器值不會小於0,或者將字元「-」新增至使用的字體排印。 為此,只需在「預設」字體排印的「萬用字元」儲存格中新增負號(「-」)即可。
教程2到此結束。