Touchgfx利用PixelDataWidget控件制作简易的函数图像

就是菜啊!

      该文章主要介绍的是利用touchgfx提供的PixelDataWidget控件来制作简易的函数图像

开发环境:

touchgfx designer13.0   、visual studio2019   、keil5 -5.27

UI界面设计:

打开Touchgfx designer,创建一个screen,添加一个box充当背景,添加一张图片,充当坐标系的背景图片,再添加三个按钮,分别是控制显示Sin(x)、SQR(方波)、Cos(x)函数图像,具体配置入下图所示:

在touchgfx designer上的工作就这么多,点击运行,然后生成代码,用vs打开该项目工程。

软件代码编写:

        因为我创建了两个Screen,并且将函数图像显示设置为Screen2,所以我是打开的Screen2ViewBase.hpp文件,首先在该文件的顶部添加PixelDataWidget.hpp文件

#include <touchgfx/widgets/PixelDataWidget.hpp>

然后在该文件中定义一个PixelDataWidget对象,并且添加按钮点击事件的回调函数。具体代码如下所示。

    /*
     * Callback Declarations
     */
    touchgfx::Callback<Screen2ViewBase, const touchgfx::AbstractButton&> buttonCallback;

    /*
     * Callback Handler Declarations
     */
    void buttonCallbackHandler(const touchgfx::AbstractButton& src);               //声明按钮点击事件的回调函数
	touchgfx::PixelDataWidget pixelDataWidget;                                     //创建PixelDataWidget对象

点击保存该文件,然后打开Screen2ViewBase.cpp文件

在文件头部添加如下代码:

#include <math.h>                        //需要借助sin(x)、cos(x)函数计算轨迹

#define PIXEL_W  200                     //bitmap的宽度
#define PIXEL_H  150                     //bitmap的高度

unsigned char button_flag = 0;

unsigned char pixe_data[PIXEL_H * PIXEL_W * 4 + PIXEL_W * 4 + 3];

 其中pixe_data数组是用来存放自己绘制的bitmap。然后将buttonCallback与回调函数进行绑定,如下图所示:

在Screen2ViewBase()中实例化PixelDataWidget对象,主要设置位置参数,位图大小,位图存储地址,以及位图格式等参数信息,具体配置入下图所示:

 

 代码如下:

 pixelDataWidget.setPosition(100, 250, PIXEL_W, PIXEL_H);            //bitmap所放置的位置,以及大小
    pixelDataWidget.setPixelData(pixe_data);                            //像素数据矩阵存储地址
    pixelDataWidget.setBitmapFormat(Bitmap::ARGB8888);                  //位图格式
    pixelDataWidget.setAlpha(255);                                      //bitmap的透明度设置
    pixelDataWidget.setTouchable(true);                                 //bitmap是否可触摸
		/*****************************************************************
		利用数组存储每个像素点的RGB数据以及透明度数据,即用4个unsigned char 来表示一个像素点的信息;
		初始化像素矩阵,每个像素点设置为白色,透明度为0,所以在页面中看不到PixelDataWidget控件(若想
		看PixelDataWidget控件所创建PIXEL_W*PIXEL_H大小的bitmap,可将下面的像素点透明度设置为255)。
		*****************************************************************/
    for (int j = 0; j < PIXEL_H; j++)
        for (int i = 0; i < PIXEL_W; i++)
        {
            pixe_data[j * PIXEL_W * 4 + i * 4 + 0] = 255;                    //蓝色点像素控制
            pixe_data[j * PIXEL_W * 4 + i * 4 + 1] = 255;                    //绿色点像素控制
            pixe_data[j * PIXEL_W * 4 + i * 4 + 2] = 255;                    //红色点像素控制
            pixe_data[j * PIXEL_W * 4 + i * 4 + 3] = 0;                      //像素点透明度控制
        }

 然后将pixelDataWidget控件添加到该页面:add(pixelDataWidget);

 因为我没有在touchgfx中为按钮设置相应的点击事件,所以要手动为每个按钮设置Action属性,具体配置如下:

 最后实现按钮事件响应的回调函数

void Screen2ViewBase::buttonCallbackHandler(const touchgfx::AbstractButton& src)
{
    unsigned int sindata[PIXEL_W] = { 0 };
		if (&src == &button1)                                   //用于切换到Screen1的按钮事件
    {
        //Interaction1
        //When button1 clicked change screen to Screen1
        //Go to Screen1 with screen transition towards East
        application().gotoScreen1ScreenSlideTransitionEast();
    }
    else if (&src == &buttonWithLabel1)                     //Sin(x)按钮被点击
    {
        for (int t = 0; t < PIXEL_W; t++)
            sindata[t] = (unsigned int)(sinf(3.14159f * 2 * t / PIXEL_W) * (PIXEL_H / 2) + (PIXEL_H / 2));   //将sin(x)函数的轨迹数据存储到数组中
    }
    else if (&src == &buttonWithLabel2)                     //SQR按钮被点击
    {
        //Interaction2
        //When buttonWithLabel_SQR clicked change color of boxWithBorder_WAV
        //Set RGB color R:115, G:108, B:108 on boxWithBorder_WAV
        for (int t = 0; t < PIXEL_W / 3; t++)
        {
            sindata[t] = 10;
            sindata[t + PIXEL_W / 3] = 140;
            sindata[t + PIXEL_W / 3 * 2] = 10;

        }
        button_flag = 2;
    }
    else if (&src == &buttonWithLabel3)                     //Cos(x)按钮被点击
    {
        for (int t = 0; t < PIXEL_W; t++)
            sindata[t] = (unsigned int)(cosf(3.14159f * 2 * t / PIXEL_W) * (PIXEL_H / 2) + (PIXEL_H / 2));  //将cos(x)函数的轨迹数据存储到数组中
			
			 button_flag = 3;
    }


    for (int j = 0; j < PIXEL_H; j++)
        for (int i = 0; i < PIXEL_W; i++)
        {

            if (sindata[i] == j)                                  //设定轨迹点像素的RGB以及透明度,这里将轨迹设置为红色,透明度为255
            {
                pixe_data[j * PIXEL_W * 4 + i * 4 + 0] = 0;
                pixe_data[j * PIXEL_W * 4 + i * 4 + 1] = 0;
                pixe_data[j * PIXEL_W * 4 + i * 4 + 2] = 255;
                pixe_data[j * PIXEL_W * 4 + i * 4 + 3] = 255;
            }
            else                                                  //将非轨迹点设定为白色,透明度为0 
            {
                pixe_data[j * PIXEL_W * 4 + i * 4 + 0] = 255;
                pixe_data[j * PIXEL_W * 4 + i * 4 + 1] = 255;
                pixe_data[j * PIXEL_W * 4 + i * 4 + 2] = 255;
                pixe_data[j * PIXEL_W * 4 + i * 4 + 3] = 0;
            }
        }
    if (button_flag == 2)
    {
        for (int i = 0; i < 130; i++)
        {
            pixe_data[i * PIXEL_W * 4 + 67 * 4 + 0 + 10 * 200 * 4] = 0;
            pixe_data[i * PIXEL_W * 4 + 67 * 4 + 1 + 10 * 200 * 4] = 0;
            pixe_data[i * PIXEL_W * 4 + 67 * 4 + 2 + 10 * 200 * 4] = 255;
            pixe_data[i * PIXEL_W * 4 + 67 * 4 + 3 + 10 * 200 * 4] = 255;

            pixe_data[i * PIXEL_W * 4 + 133 * 4 + 0 + 10 * 200 * 4] = 0;
            pixe_data[i * PIXEL_W * 4 + 133 * 4 + 1 + 10 * 200 * 4] = 0;
            pixe_data[i * PIXEL_W * 4 + 133 * 4 + 2 + 10 * 200 * 4] = 255;
            pixe_data[i * PIXEL_W * 4 + 133 * 4 + 3 + 10 * 200 * 4] = 255;
        }
    }

    for (int i = 0; i < PIXEL_W; i++)                   //X轴显示为绿色
    {
        pixe_data[75 * PIXEL_W * 4 + i * 4 + 0] = 0;
        pixe_data[75 * PIXEL_W * 4 + i * 4 + 1] = 255;
        pixe_data[75 * PIXEL_W * 4 + i * 4 + 2] = 0;
        pixe_data[75 * PIXEL_W * 4 + i * 4 + 3] = 255;
    }

    for (int j = 0; j < PIXEL_W; j++)                    //Y轴像是为黑色
    {
        pixe_data[j * PIXEL_W * 4 + 100 * 4 + 0] = 0;
        pixe_data[j * PIXEL_W * 4 + 100 * 4 + 1] = 0;
        pixe_data[j * PIXEL_W * 4 + 100 * 4 + 2] = 0;
        pixe_data[j * PIXEL_W * 4 + 100 * 4 + 3] = 255;
    }
    button_flag = 1;
    pixelDataWidget.invalidate();                        //刷新PixelDataWidget控件
}

完成这一步就离成功很近啦,接下来就是软件仿真,或者下载到开发版上面看看效果吧!关于函数图像的移动,周期缩放等,我以Sin(x)为例,可能写的比较乱,大家凑合着看看吧!

最终实验效果:

touchgfx绘制函数曲线

多周期实验效果:

touchgfx生成多周期函数图像

 

本人能力有限,可能有讲述有误的地方,欢迎大家指出来!

猜你喜欢

转载自blog.csdn.net/songjun007/article/details/107577567