跳转到主要内容

自定义容器

在创建应用时,您可能需要一个在 TouchGFX 中包含的标准控件集合中找不到的控件。

一种创建自定义控件的方法是使用自定义容器。 自定义容器是一个包含其他现有控件的对象,它组合了这些控件的视觉表现和行为。 它与传统的复合设计模式并无不同,我们也将包含的控件称为容器的子容器。

自定义容器的绘制性能通常会很高。 它会利用TouchGFX的底层绘图机制,并确定容器的哪些部分和子容器需要自动重新绘制。 这意味着在使用容器时无需担心绘图性能。

但是,有时候可能需要减少控件的空间占用量,在这种情况下,更高级的自定义控件方法可能更合适。

在TouchGFX Designer中

如果您需要在TouchGFX Designer中创建和使用自定义容器,我们在下面的视频中提供了如何在项目中使用它们的通俗介绍:

复合自定义容器

可以创建由其他自定义容器组成的自定义容器。 这可能是一种用更小的组件创建组件的有效方式。 为此,您可以添加在“控件”菜单中找到的已定义自定义容器的实例:

插入自定义容器的实例

请注意,TouchGFX Designer将帮助您避免插入会导致循环引用的实例,如向自身定义添加自定义容器实例:

潜在循环引用导致无法插入实例

自定义触发条件和操作

自定义容器的一个强大之处是能够指定自定义触发条件(回调)和自定义操作(方法)。 这意味着您可以为自定义容器定义整体行为,使之不再只是控件的可重复使用集合,还可以与应用的其余部分通信。

Further reading
请阅读自定义触发条件和操作一节中关于此功能的更多内容。

在代码中

在本节中我们将在代码中创建一个自定义容器。 步骤如下:

  • 创建继承touchgfx::Container类的类
  • 将容器的所有子容器声明为成员变量
  • 设置容器的宽度和高度
  • 设置每个子容器
  • 按正确顺序将每个子容器添加到层次结构中
  • 通过方法和回调实现需要的行为

我们将从头开始,基于代码进行构建,直至得到一个简单的全功能自定义容器。

创建继承touchgfx::Container类的类

先用以下代码创建MyCustomContainer.hpp头文件。 使用C++继承来访问touchgfx::Container的方法和成员(请记住包含头文件Container.hpp):

MyCustomContainer.hpp
#include <gui/common/FrontendApplication.hpp>
#include <touchgfx/containers/Container.hpp>

class MyCustomContainer : public touchgfx::Container
{
public:
MyCustomContainer();
virtual ~MyCustomContainer() {}
virtual void initialize();

protected:
FrontendApplication& application() {
return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
}

private:

};

将容器的所有子容器声明为成员变量

在头文件中声明自定义容器将要包含的控件。 在本例中,我们将只添加一个方框myBox和一个按钮myButton

MyCustomContainer.hpp
#include <gui/common/FrontendApplication.hpp>
#include <touchgfx/containers/Container.hpp>

class MyCustomContainer : public touchgfx::Container
{
public:
MyCustomContainer();
virtual ~MyCustomContainer() {}
virtual void initialize();

protected:
FrontendApplication& application() {
return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
}

/*
* Member Declarations
*/
touchgfx::Box myBox;
touchgfx::Button myButton;

private:

};

设置容器的宽度和高度

创建cpp文件MyCustomContainer.cpp,其中包含我们刚刚创建的头文件。 使用构造函数中的setWidth()setHeight()方法,为自定义容器设置任何大小:

MyCustomContainer.cpp
#include <gui/include/containers/MyCustomContainer.hpp>

MyCustomContainer::MyCustomContainer()
{
setWidth(250);
setHeight(250);
}

void MyCustomContainer::initialize()
{

}

设置每个子容器

现在,需要在构造函数中设置每个控件的属性:

MyCustomContainer.cpp
#include <gui/include/containers/MyCustomContainer.hpp>

MyCustomContainer::MyCustomContainer()
{
setWidth(250);
setHeight(250);

myBox.setPosition(0, 0, 250, 250);
myBox.setColor(touchgfx::Color::getColorFromRGB(255, 255, 255));

myButton.setXY(40, 95);
myButton.setBitmaps(touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_ID), touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_PRESSED_ID));
}

void MyCustomContainer::initialize()
{

}

按正确顺序将每个子容器添加到层次结构中

使用构造函数中的add()方法,将控件添加为自定义容器的子容器:

MyCustomContainer.cpp
#include <gui/containers/MyCustomContainer.hpp>

MyCustomContainer::MyCustomContainer()
{
setWidth(250);
setHeight(250);

myBox.setPosition(0, 0, 250, 250);
myBox.setColor(touchgfx::Color::getColorFromRGB(255, 255, 255));

myButton.setXY(40, 95);
myButton.setBitmaps(touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_ID), touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_PRESSED_ID));

add(myBox);
add(myButton);
}

void MyCustomContainer::initialize()
{

}

通过方法和回调实现需要的行为

为了向自定义容器中添加一些行为,我们可以在MyCustomContainer.hpp中定义一些方法和回调。 在本例中,我们定义了方法doSomething(),其唯一目的是发送回调somethingHappened

MyCustomContainer.hpp
#include <gui/common/FrontendApplication.hpp>
#include <touchgfx/containers/Container.hpp>

class MyCustomContainer : public touchgfx::Container
{
public:
MyCustomContainerBase();
virtual ~MyCustomContainerBase() {}
virtual void initialize();

/*
* Callback Setters
*/
void setSomethingHappenedCallback(touchgfx::GenericCallback<>& callback)
{
somethingHappenedCallback = &callback;
}

/*
* Methods
*/
virtual void doSomething();

protected:
FrontendApplication& application() {
return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
}

/*
* Callback Emitters
*/
virtual void emitSomethingHappenedCallback()
{
if (somethingHappenedCallback && somethingHappenedCallback->isValid())
{
somethingHappenedCallback->execute();
}
}

/*
* Member Declarations
*/
touchgfx::Box myBox;
touchgfx::Button myButton;

private:

/*
* Callback Declarations
*/
touchgfx::GenericCallback<>* somethingHappenedCallback;

};

然后,为了向方法和回调添加行为,在MyCustomContainer.cpp文件中实现它们。 对于这个简单的表面级示例,我们将只发送somethingHappened回调,但您可以视需要进行自定义:

MyCustomContainer.cpp
#include <gui/containers/MyCustomContainer.hpp>

MyCustomContainer::MyCustomContainer()
{
setWidth(250);
setHeight(250);

myBox.setPosition(0, 0, 250, 250);
myBox.setColor(touchgfx::Color::getColorFromRGB(255, 255, 255));

myButton.setXY(40, 95);
myButton.setBitmaps(touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_ID), touchgfx::Bitmap(BITMAP_BLUE_BUTTONS_ROUND_EDGE_SMALL_PRESSED_ID));

add(myBox);
add(myButton);
}

void MyCustomContainer::initialize()
{

}

void MyCustomContainer::doSomething()
{
MyCustomContainer::emitSomethingHappenedCallback();
}
Further reading
关于如何创建和使用自定义容器的更多具体示例,请参考教程4: