TouchGFX之画布控件

news2025/1/16 3:32:57

TouchGFX的画布控件,在使用相对较小的存储空间的同时保持高性能,可提供平滑、抗锯齿效果良好的几何图形绘制。

TouchGFX 设计器中可用的画布控件:

  • Line
  • Circle
  • Shape
  • Line Progress
  • 圆形进度条

存储空间分配和使用​

为了生成反锯齿效果良好的复杂几何图形,需要额外的存储空间。 为此,CWR必须具有专门分配的存储缓冲区,以便在渲染过程中使用。 CWR与TouchGFX的其余部分一样,没有动态存储空间分配。

在TouchGFX Designer中,可以在屏幕属性中重写画布缓冲区大小

需要的CWR存储空间的量取决于要在应用中绘制的最大图形大小。 但是,您可以保留比最复杂形状所需内存空间更少的内存。 为了应对这种情况,CWR将图形绘制分割成较小的帧缓存部分,在这种情况下,由于有时需要不止一次地渲染图像,因此渲染时间稍长。 在模拟器模式下运行时,可以更细致地查看存储空间消耗并进行微调。 只需向main.cpp中添加函数CanvasWidgetRenderer::setWriteMemoryUsageReport(true),具体操作如下:

#include <platform/hal/simulator/sdl2/HALSDL2.hpp>
#include <touchgfx/hal/NoDMA.hpp>
#include <common/TouchGFXInit.hpp>
#include <gui_generated/common/SimConstants.hpp>
#include <platform/driver/touch/SDL2TouchController.hpp>
#include <touchgfx/lcd/LCD.hpp>
#include <stdlib.h>
#include <simulator/mainBase.hpp>
#include <touchgfx/canvas_widget_renderer/CanvasWidgetRenderer.hpp>

using namespace touchgfx;

#ifdef __linux__
int main(int argc, char** argv)
{
#else
#include <shellapi.h>
#ifdef _UNICODE
#error Cannot run in unicode mode
#endif
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    int argc;
    char** argv = touchgfx::HALSDL2::getArgv(&argc);
#endif

    touchgfx::NoDMA dma; //For windows/linux, DMA transfers are simulated
    LCD& lcd = setupLCD();
    touchgfx::SDL2TouchController tc;

    touchgfx::HAL& hal = touchgfx::touchgfx_generic_init<touchgfx::HALSDL2>(dma, lcd, tc, SIM_WIDTH, SIM_HEIGHT, 0, 0);
	
    setupSimulator(argc, argv, hal);

    // Ensure there is a console window to print to using printf() or
    // std::cout, and read from using e.g. fgets or std::cin.
    // Alternatively, instead of using printf(), always use
    // touchgfx_printf() which will ensure there is a console to write
    // to.
    //touchgfx_enable_stdio();
	CanvasWidgetRenderer::setWriteMemoryUsageReport(true);
	
    touchgfx::HAL::getInstance()->taskEntry(); //Never returns

    return EXIT_SUCCESS;
}

自定义画布控件

实现自定义画布控件需要用下列函数实现新类:

virtual bool drawCanvasWidget(const Rect& invalidatedArea) const;
virtual Rect getMinimalRect() const;

drawCanvasWidget() 必须绘制自定义控件需要绘制的任何内容,并且 getMinimalRect() 应该返回 Widget 中包含几何形状的实际矩形。

举例:在10x10方块内部粗略实现一个菱形块

Diamond10x10.hpp


#ifndef DIAMOND10X10_HPP
#define DIAMOND10X10_HPP

#include <touchgfx/widgets/canvas/CanvasWidget.hpp>
#include <touchgfx/widgets/canvas/Canvas.hpp>

using namespace touchgfx;

class Diamond10x10 : public CanvasWidget
{
public:
  virtual Rect getMinimalRect() const
  {
    return Rect(0,0,10,10);
  }
  virtual bool drawCanvasWidget(const Rect& invalidatedArea) const
  {
    Canvas canvas(this, invalidatedArea);
    canvas.moveTo(5,0);
    canvas.lineTo(10,5);
    canvas.lineTo(5,10);
    canvas.lineTo(0,5);
    return canvas.render(); // Shape is automatically closed
  }
};

#endif
screenView.hpp


#ifndef SCREENVIEW_HPP
#define SCREENVIEW_HPP

#include <gui_generated/screen_screen/screenViewBase.hpp>
#include <gui/screen_screen/screenPresenter.hpp>
#include <gui/common/Diamond10x10.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565.hpp>

class screenView : public screenViewBase
{
public:
    screenView();
    virtual ~screenView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
protected:
	
private:
	Diamond10x10 box;
	PainterRGB565 myPainter; // For 16bpp displays
};

#endif // SCREENVIEW_HPP
screenView.cpp


#include <gui/screen_screen/screenView.hpp>
#include <touchgfx/Color.hpp>

screenView::screenView()
{

}

void screenView::setupScreen()
{
    screenViewBase::setupScreen();
	
		myPainter.setColor(Color::getColorFromRGB(0xFF, 0x0, 0x0));
		box.setPosition(100,100,10,10);
		box.setPainter(myPainter);
		add(box);
}

void screenView::tearDownScreen()
{
    screenViewBase::tearDownScreen();
}

运行模拟器,效果如下(意味着画布缓冲区大小可以调整到大于168字节即可)

平铺位图

首先在模拟器中添加图片资源

然后修改程序

#ifndef DIAMOND10X10_HPP
#define DIAMOND10X10_HPP

#include <touchgfx/widgets/canvas/CanvasWidget.hpp>
#include <touchgfx/widgets/canvas/Canvas.hpp>

using namespace touchgfx;

class Diamond10x10 : public CanvasWidget
{
public:
  virtual Rect getMinimalRect() const
  {
    return Rect(0,0,100,100);
  }
  virtual bool drawCanvasWidget(const Rect& invalidatedArea) const
  {
    Canvas canvas(this, invalidatedArea);
    canvas.moveTo(50,0);
    canvas.lineTo(100,50);
    canvas.lineTo(50,100);
    canvas.lineTo(0,50);
    return canvas.render(); // Shape is automatically closed
  }
};

#endif
#ifndef SCREENVIEW_HPP
#define SCREENVIEW_HPP

#include <gui_generated/screen_screen/screenViewBase.hpp>
#include <gui/screen_screen/screenPresenter.hpp>
#include <gui/common/Diamond10x10.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565Bitmap.hpp>

class screenView : public screenViewBase
{
public:
    screenView();
    virtual ~screenView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
protected:
	
private:
	Diamond10x10 box;
	PainterRGB565Bitmap bitmapPainter;
};

#endif // SCREENVIEW_HPP
#include <gui/screen_screen/screenView.hpp>
#include <touchgfx/Color.hpp>
#include <images/BitmapDatabase.hpp>

screenView::screenView()
{

}

void screenView::setupScreen()
{
    screenViewBase::setupScreen();
	
    bitmapPainter.setBitmap(touchgfx::Bitmap(BITMAP_TEST_ID));
    bitmapPainter.setTiled(true);
		box.setPosition(100,100,100,100);
		box.setPainter(bitmapPainter);
		add(box);
}

void screenView::tearDownScreen()
{
    screenViewBase::tearDownScreen();
}

运行模拟器,效果如下

定制绘图器

尽管TouchGFX提供一组预定义的画笔类,涵盖了大多数用例场景,但也可实现定制画笔

#ifndef REDPAINTER_HPP
#define REDPAINTER_HPP

#include <touchgfx/widgets/canvas/AbstractPainterRGB565.hpp>

using namespace touchgfx;

class StripePainter : public AbstractPainterRGB565
{
public:
    virtual void paint(uint8_t* destination, int16_t offset, int16_t widgetX, int16_t widgetY, int16_t count, uint8_t alpha) const
    {
        if ((widgetY & 2) == 0)
        {
            return; // Do not draw anything on line 0,1, 4,5, 8,9, etc.
        }
        uint16_t* framebuffer = reinterpret_cast<uint16_t*>(destination) + offset;
        const uint16_t* const lineend = framebuffer + count;
        if (alpha == 0xFF)
        {
            do
            {
                *framebuffer = 0xF800;
            } while (++framebuffer < lineend);
        }
        else
        {
            do
            {
                *framebuffer = alphaBlend(0xF800, *framebuffer, alpha);
            } while (++framebuffer < lineend);
        }
    }
};

#endif
#ifndef SCREENVIEW_HPP
#define SCREENVIEW_HPP

#include <gui_generated/screen_screen/screenViewBase.hpp>
#include <gui/screen_screen/screenPresenter.hpp>
#include <gui/common/Diamond10x10.hpp>
#include <gui/common/RedPainter.hpp>

class screenView : public screenViewBase
{
public:
    screenView();
    virtual ~screenView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
protected:
	
private:
	Diamond10x10 box;
	StripePainter myPainter;
};

#endif // SCREENVIEW_HPP
#include <gui/screen_screen/screenView.hpp>
#include <touchgfx/Color.hpp>

screenView::screenView()
{

}

void screenView::setupScreen()
{
    screenViewBase::setupScreen();
	
		box.setPosition(100,100,100,100);
		box.setPainter(myPainter);
		add(box);
}

void screenView::tearDownScreen()
{
    screenViewBase::tearDownScreen();
}

运行模拟器,效果如下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1031724.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「UG/NX」BlockUI 选择小平面区域 Select Facet Region

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「UG/NX」BlockUI集合&#x1f4da;全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C」C/C程序设计「Win」Windows程序设计「DSA」数据结构与算法「File」数据文件格式 目录 控件说…

深入探究序列化与反序列化:原理、应用和最佳实践

目录 什么是对象的序列化和反序列化序列化步骤反序列化步骤案例演示Java中哪些字段不能序列化序列化与反序列化的重要性序列化与反序列化的应用场景 什么是对象的序列化和反序列化 序列化&#xff08;Serialization&#xff09;是指将对象转化为字节流的过程&#xff0c;以便于…

点燃创意,发掘绘图潜能——FireAlpaca for Mac专业绘图软件

无论您是一位艺术家、插画师还是爱好绘图的人&#xff0c;寻找一款功能强大且易于使用的绘图软件都是必不可少的。而FireAlpaca for Mac作为一款专为Mac用户设计的专业绘图软件&#xff0c;将点燃您的创意&#xff0c;帮助您发掘绘图的潜能。 FireAlpaca for Mac拥有丰富的工具…

Linux,计算机网络,数据库

Linux&#xff0c;计算机网络&#xff0c;数据库&#xff0c;操作系统 一、Linux1、linux查看进程2、linux基本命令3、top命令、查看磁盘 二、计算机网络1、HTTP的报文段请求 Repuest响应 Response 2、HTTP用的什么连接3、TCP的三次握手与四次挥手三次握手四次挥手 4、在浏览器…

【RabbitMQ实战】02 生产者和消费者示例

在上一节中&#xff0c;我们使用docker部署了RabbitMQ&#xff0c;这一节我们将写一段生产者和消费者的代码。将用到rabbitmq的原生API来进行生产和发送消息。 一、准备工作 开始前&#xff0c;我们先在RabbitMQ控制台建相好关的数据 本机的RabbitMQ部署机器是192.168.56.201…

竞赛 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

【操作系统笔记五】内存布局内存映射

虚拟内存布局 虚拟地址空间大小&#xff1a; 32位虚拟地址空间 [0 ~ 2^32 - 1] 总共4GB64位虚拟地址空间 [0 ~ 2^64 - 1] 总共16 777 216TB 不管是运行在用户态还是内核态&#xff0c;都需要使用虚拟地址&#xff0c;这是因为计算机硬件要求的&#xff0c;CPU要经过地址转换得…

观测云产品更新 | 优化日志数据转发、索引绑定、基础设施自定义等

观测云更新 日志 数据转发&#xff1a;新增外部存储转发规则数据查询&#xff1b;支持启用/禁用转发规则&#xff1b;绑定索引&#xff1a;日志易新增标签绑定&#xff0c;从而实现更细颗粒度的数据范围查询授权能力。 基础设施 > 自定义 【默认属性】这一概念更改为【必…

绝佳盘点:2023年最好用的AI机器人

近几年人工智能可以说是以前所未有的速度在发展&#xff0c;越来越多的企业意识到&#xff0c;在运营的过程中学会熟练地应用AI机器人是可以帮助他们很好地提高工作效率的。那么有哪些AI机器人比较好用呢&#xff1f;接下来我会介绍几个个人觉得比较优秀的AI机器人工具&#xf…

【51单片机】6-点亮第一个LED灯

1.单片机编程的一般步骤 1.目标分析 点亮开发板上的LED灯 2.原理图【电路图】分析 1.目标器件&#xff08;LED&#xff09;工作原理 2.相关模块电路连接 3.控制线路分析&#xff1a;相关IO端口是哪些&#xff1f; 3.代码编写&#xff0c;编译 4.下载于调试 2.原理图与控制…

杂记 | 使用gitlab-runner将python项目以docker镜像方式流水线部署到服务器(解决部署缓慢和时区不对的问题)

文章目录 01 需求背景1.1 需求1.2 步骤 02 编写BaseDockerfile2.1 编写2.2 说明2.3 执行 03 编写Dockerfile04 编写.gitlab-ci.yml05 项目结构 01 需求背景 1.1 需求 我有一个python项目&#xff0c;该项目可能是一个服务器监控程序&#xff0c;也可能是一个后端程序&#xf…

【开关稳压器】LMR16030SDDA、LMR38010FDDAR,汽车类LMR43610MSC5RPERQ1低 EMI 同步降压稳压器

一、LMR16030SDDA 开关稳压器 IC REG BUCK ADJ 3A 8SOPWR LMR16030 是一款带有集成型高侧 MOSFET 的 60V、3A SIMPLE SWITCHER 降压稳压器。该器件具有4.3V 至 60V 的宽输入范围&#xff0c;适用于从工业到汽车各类应用中非稳压电源的电源调节。该稳压器在睡眠模式下的静态电流…

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(二)

目录 前言总体设计系统整体结构图系统流程图 运行环境模块实现1. 模型训练1&#xff09;数据集分析2&#xff09;数据预处理 相关其它博客工程源代码下载其它资料下载 前言 本项目专注于MovieLens数据集&#xff0c;并采用TensorFlow中的2D文本卷积网络模型。它结合了协同过滤…

h5下载文件,无兼容问题~

最近写了个页面&#xff0c;打开页面出现文件列表&#xff0c;用户可以下载文件。 失败方案 使用a标签进行下载&#xff0c;参考代码如下&#xff1a; 因为有批量下载的需求&#xff0c;这里将xhr请求单独封装到downloadFile.js中 // downloadFile.js const downloadFile …

Flutter超好用的路由库-fluro

文章目录 fluro的介绍fluro简介安装和导入路由配置导航到路由参数传递 fluro的典型使用创建路由管理类代码解释例子小结 初始化路由导航到路由 总结 fluro的介绍 fluro简介 fluro是一个流行的Flutter插件&#xff0c;用于实现高级路由管理。它提供了灵活的路由配置和导航功能…

VR科普研学基地科普开放日普乐蛙VR体验馆沉浸式体验设备

广州科普开放日来啦 2023年9月广州科普开放日来啦&#xff0c;9月16日周六上午9点&#xff0c;广州卓远非常荣幸地迎来了一批前来体验的家庭。 比原定的集合时间提前了近1个小时&#xff0c;已经开始有家长带着小朋友来到了VR科普基地&#xff0c;可见大家对VR科普体验的热情和…

轻量服务器是不是vps ?和vps有什么区别

​  轻量型服务器是介于云服务器和共享型服务器之间的一种解决方案。它提供较为独立的资源分配&#xff0c;但规模较小&#xff0c;适用于中小型网站和应用程序。轻量型服务器的硬件资源来源于大型的公有云集群的虚拟化技术。轻量型服务器的性能和带宽可能会稍逊于云服务器。…

【笨~~~】在python中导入另一个模块的函数时,为什么会运行模块中剩下的部分??顶层?

一个程序员一生中可能会邂逅各种各样的算法&#xff0c;但总有那么几种&#xff0c;是作为一个程序员一定会遇见且大概率需要掌握的算法。今天就来聊聊这些十分重要的“必抓&#xff01;”算法吧~ Python导入了其他文件中的函数&#xff0c;运行时连着这个文件一起运行了 在py…

椭圆曲线加密算法

椭圆曲线密码学&#xff08;Elliptic curve cryptography&#xff09;&#xff0c;简称ECC&#xff0c;是一种建立公开密钥加密的算法&#xff0c;也就是非对称加密。类似的还有RSA&#xff0c;ElGamal算法等。ECC被公认为在给定密钥长度下最安全的加密算法。比特币中的公私钥生…

什么是文档签名证书?PDF文档怎么签名?

什么是文档签名证书&#xff1f;在“互联网”时代&#xff0c;电子合同、电子证照、电子病历、电子保单等各类电子文档无纸化应用成为常态。如何让电子文档的签署、审批具有公信力及法律效力&#xff0c;防止伪造签名、假冒签名等问题出现&#xff0c;是电子文档无纸化应用的主…