跳转到主要内容

教程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 uVision 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
  • 关于文本的更多信息,请阅读“文本和字体”页面。