跳转到主要内容

教程2:创建您自己的应用

请跟随本教程学习TouchGFX的更多基本知识。 您将学习如何将图像添加到应用以及如何使用按钮。 您还将学习如何使用文本和计算值。 在最后的步骤中,您将编写代码,以便增强使用TouchGFX Designer创建的UI的视觉效果。 本教程假设您没有TouchGFX的相关知识,但是有一点编程的经验。

第1步:设置背景图像

在第一个步骤中,您将看到如何插入PNG图像作为背景。 但首先我们将新建一个项目。

新建一个项目

在TouchGFX Designer中启动新项目。 我们将该项目命名为“MyApplication1”。 该项目基于“STM32F746G探索套件”。

如果您有其他STM32评估套件,请查看TouchGFX Designer提供的支持的设备列表中是否包含此套件。 如果您没有支持的板卡,可以选择“模拟器”,并直接在Windows计算机上运行应用。

请注意,本教程在分辨率为480x272的显示屏上运行。 如果您选择具有其他分辨率的应用模板,则图形与屏幕将不匹配,尽管如此,您仍应能够完成本教程。

使用STM32F746新建项目

现在,有一个新建的空白项目,我们开始修改它。

TouchGFX应用包含许多屏幕。 屏幕包含许多控件,它们共同构成了用户屏幕。 屏幕覆盖整个显示屏,因此一次只能向用户显示一个屏幕。

首先要做的是将初始屏幕的名称修改为“Main”,如下图所示。 在左侧列表中选择该屏幕 (1),并在右侧的名称字段中修改名称 (2)。 也可通过双击或右键单击列表的屏幕 (1) 来重命名屏幕。

12

修改屏幕名称

插入背景

用一个或多个控件覆盖屏幕的整个背景通常是个不错的选择。 例如,可以是方块或图像。 如果不覆盖,背景将显示为黑色。 在本应用中,我们将使用图像。

我们需要导入文件,然后才能在TouchGFX Designer中使用图像。 TouchGFX支持BMP和PNG图像(尽管TouchGFX Designer只支持导入PNG图像)。 PNG文件优先于BMP文件,原因是前者更小且支持透明像素。

本教程将使用的图像可从此链接下载。 将文件解压缩到磁盘上的目录。

我们想要使用名为“background.png”的文件作为背景。 为了导入该文件:

  • 选择“图像”选项卡并点击“+”按钮。
  • 导航到解压缩文件夹并选择“background.png”文件。
  • 按下“打开”按钮导入文件。

为了将文件导入项目,您还可以将文件浏览器中的图像拖&放到“图像”选项卡上,甚至直接拖放到画布上。

请注意,导入项目的图像会被转换并编译到项目中,因此会占用闪存空间。 请只导入需要的图像。 为了添加图像,点击左侧的“图像”按钮 (1),然后点击右侧的“+”按钮 (2)。 TouchGFX Designer打开普通的文件浏览器,在这里您可以导航到下载的图像并选择“background.png”文件。

12

图像background.png被导入

现在,我们可以在应用中使用该图像。 为此,我们需要一个图像控件。

  • 点击左侧的“画布”按钮 (1)
  • 在控件列表中找到图像控件 (2)
  • 点击它在屏幕上插入图像控件。

最好为控件改一个有意义的名称。 在本例中,我们使用“backgroundImage”(3)。

123

插入图像控件

在插入控件后,通常需要配置它的一些属性,如位置颜色。 在TouchGFX Designer中,所选控件的属性显示在右侧。 屏幕中的控件显示在左侧的树视图中 (1)。 在本例中,我们对位置所在的点 0,0 感到满意,但想要修改图像属性,以便选择之前导入的文件“background.png”。 点击图像属性 (2) 并选择“background.png”。

12

选择导入的图像文件作为背景

现在,我们已经创建了一个简单的应用,它有一个只包含一张覆盖了整个用户屏幕的背景图像的屏幕。

在继续操作前,尝试按下“运行模拟器”按钮,以便确认项目正常编译和运行。 由于尚未添加任何活动的控件,因此现在还不能与应用交互。

第2步:添加按钮

在这一步中,我们将为应用添加两个按钮,并用不同的PNG文件给予它们自定义外观。

添加按钮

  • 为了将按钮添加到屏幕,点击“控件”选项卡上的按钮控件 (1)。
  • 用鼠标拖拽新的控件以便移动它。
  • 将按钮定位在位置 (x=40, y=60) 处。 检查右侧属性中的位置 (2)。
  • 将新的控件命名为“buttonUp”。
  • 在位置 x=40, y=150 处添加另一个按钮。 将此控件命名为“buttonDown”。

现在,项目如下图所示:

12

添加两个按钮

您可以使用X和Y属性的向上/向下小按钮对控件的位置进行微调。 您也可以选中按钮控件(在画布上点击它),然后用键盘上的箭头键调整位置。

修改外观

现在,我们将修改按钮的外观。 按钮由两幅图像构成。 一幅图像在按钮被按下时显示,另一幅图像在按钮未被按下(释放)时显示。 大多数控件都附带一组预定义样式,实际上是描述控件具体外观的一组特定属性值。 这些样式有助于进行快速的原型开发,但在创建实际应用时,通常会将它们替换掉。

像上一步一样转至“图像”选项卡,并点击右上角的“+”图标导入一些图像。 此次导入四张图像:“button_down_pressed.png”、“button_down_released.png”、“button_up_pressed.png”和“button_up_released.png”。

添加四张按钮图像

可以看到,虽然我们只导入了5张图像,但项目中共有7张图像。 另外两张是按钮上默认使用的蓝色图像。 当不再使用时,这些图像会被自动删除。

回到画布并选择“buttonUp”按钮。 点击“释放图像”属性 (1),然后点击“项目”显示图像 (2),最后选择正确的图像 (3)。 对于“buttonUp”,为“释放图像”属性选择“button_up_released.png”。 为“按下图像”属性选择“button_up_pressed.png”。

123

设置按钮图像

您可以立即看到TouchGFX Designer中画布上按钮的外观。

为按钮设置位图

对于“buttonDown”,为“释放图像”选择“button_down_released.png”,为“按下图像”选择“button_down_pressed.png”。

现在,您已完成按钮的设置。 点击“运行模拟器”尝试运行应用。

尝试使用两个按钮,以便确认按钮配置正确。

运行模拟器

Tip
TouchGFX中的大多数控件使用图像来定义其大小,这意味着无法直接调整其大小。 这样做是出于性能考虑(参见“一般UI组件性能”)。 如需修改此类控件的大小,如本教程中的按钮,方法是为按钮新建一组图像并将它们用作“释放图像”和“按下图像”。

第3步:添加文本

在这一步中,我们将为应用添加一个大尺寸的TextArea工具。

所有文本均通过TextArea工具来显示,但在将TextArea添加到应用之前,我们先添加另一张图像,以便为文本提供一个更好的背景。

文本背景

  • 导入另一个图像文件“counter_box.png”。
  • 插入新的图像控件
  • 将其命名为“textBackground”
  • 将其定位在位置 (x=250, y=59) 处。
  • 图像属性设置为“counter_box”。

为文本添加了背景

添加文本

现在,我们可以添加TextArea控件。 点击“控件/其他”下拉菜单中的TextArea图标。 将控件重命名为“textCounter”,并将控件移动到位置 (x=250, y=90) 处。 我们要让控件显示大文本,因此取消选中“自动调整大小”属性,并将尺寸设置为固定宽度=152和高度=90。

添加了TextArea

TextArea控件的默认色彩是黑色,在背景上显得很暗。 选择“textCounter”的颜色 属性,将颜色修改为白色。

修改文本色彩

修改文本字体排印

我们要让文本更大。 为此,需修改文本使用的“字体排印”。 字体排印定义了文本的“字体”(如Verdana)、“尺寸”“对齐”(左、右或中心)。

选择TouchGFX Designer左上角的“文本”选项卡 (1),点击“字体排印”(2),并将“默认”字体排印的大小更新为80 (3)。

123

修改文本大小

回到屏幕(点击左上角的“画布”选项卡),现在我们可以看到文本大了许多。 事实上,我们无法读取完整的文本“新文本”。 点击对齐 属性下的中心对齐图标让文本中心对齐 (1)。

1

修改文本对齐方式

使用通配符文本

我们要让TextArea显示一个可以用按钮修改的数字。 为此,我们必须修改文本,以便包含“通配符”。 通配符是文本中的一种标记(“<d>”),在运行时可以用其他一些字符(如数字)代替。 我们只想显示一个数字,因此将文本修改为简单的“<d>”。 在其他项目中,您可以将动态部分与固定文本进行组合,如“温度:<temp>°C"。

Note
<...>通配符括号内的文本是可选的。 您可以使用它们将通配符中插入的信息类型传递给实现器或翻译器,或者也可以保留空白。

将文本修改为“<d>”(1),点击“通配符1”(2),将默认值设置为“0”,并选中“使用通配符缓冲区”。

12

配置通配符文本

点击“运行模拟器”尝试运行应用。

运行模拟器

Further reading
关于使用文本和字体的更多信息,请阅读“文本和字体”页面。

第4步:添加代码

使用TouchGFX Designer时,可轻松地通过交互将操作链接到按钮。 交互将触发条件(如按钮按下)链接到操作(如运行代码或移动元素)。

选择右上角的“交互”选项卡 (1),点击“+”按钮新建交互。

1

添加交互

我们将创建两个交互,每个按钮一个。 我们将两个交互都设置用来在当前屏幕上调用C++方法。

  • “触发条件”属性修改为“点击按钮”。
  • “选择点击源”属性设置为“buttonUp”。
  • “操作”属性修改为“调用新的虚拟函数”。
  • “函数名称”字段键入“buttonUpClicked”。
  • 您还应为交互取一个描述性的名称,以方便以后识别。

配置按钮交互

用“buttonDown”创建相似交互“clicked source”:

  • 点击“+”启动新的交互。
  • “触发条件”属性修改为“点击按钮”。
  • 选择点击源 属性设置为“buttonDown”。
  • “操作”属性修改为“调用新的虚拟函数”。
  • 对于函数名称,输入"buttonDownClicked"。
  • 您还应为交互取一个描述性的名称,以方便以后识别。

如果您点击“生成代码”按钮或“运行模拟器”按钮,TouchGFX Designer将用您在刚创建的交互中输入的信息更新生成的代码。 这意味着它将在View基类中为该屏幕创建两个新的虚拟函数。

我们进一步研究如何能够执行自己的代码。 点击右下角的“生成代码”按钮,然后点击左下角的“文件”按钮。 打开的文件浏览器定位在应用文件夹。 导航到以下文件夹:

MyApplication1/TouchGFX/generated/gui_generated/include/gui_generated/main_screen/

并打开文件MainViewBase.hpp。 如果您愿意,还可以打开一个项目文件并在IDE中找到该文件:

IDE项目文件路径
STM32CubeIDEMyApplication1/STM32CubeIDE/.project
Visual StudioMyApplication1/TouchGFX/simulator/msvs/Application.sln
IAR Embedded Workbench 8MyApplication1/EWARM/Project.eww
KEIL μVision v5MyApplication1/MDK-ARM/STM32F746G_DISCO.uvprojx
Note
并非所有项目文件都默认显示。 为了修改项目的工具链,您需要使用STM32CubeMX工具。 关于这一点的更多信息,请阅读“使用IDE和TouchGFX”页面。

新的虚拟函数位于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)。

1

为“默认”字体排印设置“通配符范围”

现在,再次点击“运行模拟器”,然后点击几次“向上”按钮:

运行模拟器

程序现在还不能正确地处理负数。 为了解决这个问题,可在buttonDownClicked()函数中插入guard以确保计数器值不会小于0,或者将字符“-”添加到使用的字体排印。 为此,只需在“默认”字体排印的“通配符字符”单元格中添加负号(“-”)即可。

教程2到此结束。

Further reading
  • 关于文本的更多信息,请阅读“文本和字体”页面。