Awtk 如何添加开机画面

news2025/2/13 3:49:53

场景

        我们知道在工程中,Ui是一个线程,并且需要一直存在,当我们使用的开机画面在这个线程开启就直接展示的时候,因为awtk的界面是window_open入栈的,即首次打开的窗口会记录在top,往后的窗口会依次往后存放,并记录位置,当跳回主界面的时候,此时调用的window_manager_back_to_home/window_manager_get_top_window会出现开机界面,因此开机画面如果不做回收释放,就会一直存在。

        如果要做回收释放,开机界面必须要实现为,可以释放内存的堆结构,并且记录窗口指针,提供外部释放。(同时需要注意一点,window_open调用和释放窗口指针等结构都必须要在ui线程,防止多线程操作死机。)后续在跳回主界面的时候,就会直接回到主界面,而不会回到开机界面,但是当显示是开机界面,如果加入其他界面呢?,就需要采用idle_queue添加主窗口(交互界面中,主窗口为其他窗口的入口)了。

//主窗口某一按键功能,位于ui线程
  if (evt->key == TK_KEY_F10) {
        window_manager_back_to_home(wm);  
        //如果没有释放开机界面,回不到主窗口,并且操作会挂掉。
        //win = window_manager_get_top_window(wm);
        win = widget_child(window_manager(), "win_main");
        return_value_if_fail(win != NULL, RET_STOP);
        button_win_pages_set(win,FALSE);
        return RET_STOP;
    } 
    ...

具体更改实现

主线程

//假设主函数有ui线程和work线程。
int main(int argc,char* argv[])
{
    thread_start(WinMain(ui线程));
    thread_start(work线程);
    while(1)
    {
        delay(1);
    }
}

ui线程

int WinMain(void)
{

    int lcd_w = 800;
    int lcd_h = 480;
#if defined(LCD_W) && defined(LCD_H)
    lcd_w = LCD_W;
    lcd_h = LCD_H;
#endif

#ifdef WITH_FS_RES
    char res_root[MAX_PATH + 1];
    char app_root[MAX_PATH + 1];
    path_app_root(app_root);
    memset(res_root, 0x00, sizeof(res_root));
#if LCD_W == 480
    path_build(res_root, MAX_PATH, app_root, "res_480_272", NULL);
#else
    path_build(res_root, MAX_PATH, app_root, "res_800_480", NULL);
#endif

    tk_init(lcd_w, lcd_h, APP_SIMULATOR, NULL, res_root);
#else
    tk_init(lcd_w, lcd_h, APP_SIMULATOR, NULL, NULL);
#endif

#endif

//#define WITH_LCD_PORTRAIT 1
#if defined(USE_GUI_MAIN) && defined(WITH_LCD_PORTRAIT)
    if (lcd_w > lcd_h) {
        tk_set_lcd_orientation(LCD_ORIENTATION_90);
    }
#endif /*WITH_LCD_PORTRAIT*/

#ifdef WITH_LCD_LANDSCAPE
    if (lcd_w < lcd_h) {
        tk_set_lcd_orientation(LCD_ORIENTATION_90);
    }
#endif /*WITH_LCD_PORTRAIT*/

    /* 初始化资源 */
    assets_init();

    /*初始化扩展和自定义窗口*/
    tk_ext_widgets_init();

    custom_widgets_init();

    /* 实现UI app应用 即用户界面主入口*/
    application_init();  //进入用户的ui界面

    _gui_init_done = 1;

    /* awtk死循环运行 */
    tk_run();

    return 0;
}

static void* pwin=NULL;
void setprogress_bar(int progress) //外部触发ui释放窗口内存。
{
  if(pwin)
  {
    close_Swin(pwin);
    pwin=NULL;
  }
}

ret_t application_init(void) {
#if 1
  pwin=awtk_show_start_box();   //只刷新开机界面 ,并记录窗口句柄
  return_value_if_fail(awtk_adapter_init() != RET_OK, RET_FAIL);    
#else //同时打开开机界面和主界面的方式是不正确的
  pwin=awtk_show_start_box();
  open_win_application();
  return_value_if_fail(awtk_adapter_init() != RET_OK, RET_FAIL);    
#endif

  return RET_OK;
}


ret_t open_win_application(void) //主窗口是打开其他窗口的入口。
{
    common_id_string_tab_init();

    open_window_manager();  //管理所有窗口

    open_sys_bar();

    widget_t* win = window_open("win_main");
    return_value_if_fail(win != NULL, RET_FAIL);

    common_win_pages_set(win);
    button_win_pages_set(win,FALSE);

    widget_t* canvas = canvas_widget_create(win,10,180,60 ,48);

    widget_on(canvas, EVT_PAINT, on_paint_vgcanvas, NULL);
    common_id_fun_tab_foreach(win, win_main_fun_tab, WIN_MAIN_FUN_TAB_SIZE, PM_UPDATE_PARAM);

    widget_on(win, EVT_KEY_DOWN, on_win_key_down, win);
    widget_foreach(win, init_widget, win);

    return RET_OK;
}

static ret_t idle_close_start_box( const idle_info_t* idle )
{
    return_value_if_fail( idle != NULL, RET_BAD_PARAMS );
    idle_data_t* p_data = (idle_data_t*)( idle->ctx );
    if ( p_data && p_data->win ) {
        p_data->callfun_b_enter = FALSE;
        timer_remove(p_data->timer_id);
        window_close( p_data->win );  //释放窗口
        win_close_need_free_mem( p_data );
    };
    return RET_OK;
}

void close_Swin( void* p )  //必须ui线程调用
{
    idle_queue( idle_close_start_box, p );
}
//开机界面必须使用堆创建的方式,直接静态界面,直接将界面缓存在内部管理的链表中,
//如果没有提供外部释放接口。在返回top层,开启home界面的时候,显示的就不是主界面,
//而是开机界面。不符合设计。并且此时操作界面按键,会引起死机。
static ret_t idle_show_start_box( const idle_data_t* idle )
{
    return_value_if_fail( idle != NULL, RET_BAD_PARAMS );
    idle_data_t* p_data = idle;

    widget_t* win = window_open( "home" );//win_debug

    if ( win == NULL ) {
        win_close_need_free_mem( p_data );
        return RET_BAD_PARAMS;
    }

    widget_t* title = widget_get_child( win, 0 );
    widget_t* client = widget_get_child( win, 1 );

    widget_t* widget = NULL;
    p_data->win = win;  //记录窗口,供外部释放。
    //if ( p_data->dis_type == MSGBOX_DIS_DELAY ) {
        widget = widget_get_child( client, 1 );
        widget_set_visible( widget, FALSE, TRUE );
        widget = widget_get_child( client, 2 );
        widget_set_visible( widget, FALSE, TRUE );
        p_data->timer_id = timer_add( on_timer_Sclose_win, p_data, 500 );
    //}
    return RET_OK;
}

void* awtk_show_start_box()
{
    idle_data_t* p = TKMEM_ZALLOC( idle_data_t ); //awtk内部堆申请内存
    if(p)
    {
        wstr_init( &p->text, WSTRLENTH );
        wstr_set_utf8( &p->text, "" );
        p->info_type = 0;
        p->dis_type = 0;
        p->callfun = NULL;
        p->win = NULL;
        idle_show_start_box(p);
    }
    return p;
}

work线程

uint32_t work线程()
{
    //dosomething ......
    idle_queue( OnAwtkUiDone, this );  //通过这个接口往ui线程添加主窗口,
    //dosomething ......                             
}

ret_t OnAwtkUiDone( const idle_info_t* idle )
{
    CCoreEngine* pCore = (CCoreEngine*)idle->ctx;
    if ( pCore )
    {
        pCore->OnGuiStartDone();
    }
    return RET_REMOVE;
}

void CCoreEngine::OnGuiStartDone()
{
#if OPEN_AWTK
    setprogress_bar(100);  //当bar到达100%后,释放开机界面
    open_win_application();   //引入主界面
#endif
}

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

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

相关文章

【设计模式】【行为型模式】命令模式(Command)

&#x1f44b;hi&#xff0c;我不是一名外包公司的员工&#xff0c;也不会偷吃茶水间的零食&#xff0c;我的梦想是能写高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f4eb; 欢迎V&#xff1a; flzjcsg2&#xff0c;我们共同讨论Java深渊的奥秘 &#x1f…

C++模拟实现AVL树

目录 1.文章概括 2.AVL树概念 3.AVL树的性质 4.AVL树的插入 5.旋转控制 1.左单旋 2. 右单旋 3.左右双旋 4.右左双旋 6.全部代码 1.文章概括 本文适合理解平衡二叉树的读者阅读&#xff0c;因为AVL树是平衡二叉树的一种优化&#xff0c;其大部分实现逻辑与平衡二叉树是…

python卷积神经网络人脸识别示例实现详解

目录 一、准备 1&#xff09;使用pytorch 2&#xff09;安装pytorch 3&#xff09;准备训练和测试资源 二、卷积神经网络的基本结构 三、代码实现 1&#xff09;导入库 2&#xff09;数据预处理 3&#xff09;加载数据 4&#xff09;构建一个卷积神经网络 5&#xff0…

以Unity6.0为例,如何在Unity中开启DLSS功能

DLSS DLSS&#xff08;NVIDIA 深度学习超级采样&#xff09;&#xff1a;NVIDIA DLSS 是一套由 GeForce RTX™ Tensor Core 提供支持的神经渲染技术&#xff0c;可提高帧率&#xff0c;同时提供可与原生分辨率相媲美的清晰、高质量图像。目前最新突破DLSS 4 带来了新的多帧…

CSDN 大模型 笔记

AI 3大范式&#xff1a;计算 发发 交互 L1 生成代码 复制到IDEA &#xff08;22年12-23年6&#xff0c;7月份&#xff09; L2 部分自动编程 定义class 设计interface 让其填充实现 (23年7&#xff0c;8月份) L3 通用任务 CRUD (24年) L4 高度自动编程 通用领域专有任务&#xf…

Stability AI 联合 UIUC 提出单视图 3D 重建方法SPAR3D,可0.7秒完成重建并支持交互式用户编辑。

Stability AI 联合 UIUC 提出一种简单而有效的单视图 3D 重建方法 SPAR3D&#xff0c;这是一款最先进的 3D 重建器&#xff0c;可以从单视图图像重建高质量的 3D 网格。SPAR3D 的重建速度很快&#xff0c;只需 0.7 秒&#xff0c;并支持交互式用户编辑。 相关链接 论文&#xf…

网易易盾接入DeepSeek,数字内容安全“智”理能力全面升级

今年农历新年期间&#xff0c;全球AI领域再度掀起了一波革命性浪潮&#xff0c;国产通用大模型DeepSeek凭借其强大的多场景理解与内容生成能力迅速“出圈”&#xff0c;彻底改写全球人工智能产业的格局。 作为国内领先的数字内容风控服务商&#xff0c;网易易盾一直致力于探索…

自动驾驶---如何打造一款属于自己的自动驾驶系统

在笔者的专栏《自动驾驶Planning决策规划》中&#xff0c;主要讲解了行车的相关知识&#xff0c;从Routing&#xff0c;到Behavior Planning&#xff0c;再到Motion Planning&#xff0c;以及最后的Control&#xff0c;笔者都做了相关介绍&#xff0c;其中主要包括算法在量产上…

聚焦 AUTO TECH China 2025,共探汽车内外饰新未来Automotive Interiors

全球汽车产业蓬勃发展的大背景下&#xff0c;汽车内外饰作为汽车重要组成部分&#xff0c;其市场需求与技术创新不断推动着行业变革。2025年11月20日至22日&#xff0c;一场备受瞩目的行业盛会 ——AUTO TECH China 2025 广州国际汽车内外饰技术展览会将在广州保利世贸博览馆盛…

Moretl 增量文件采集工具

永久免费: <下载> <使用说明> 用途 定时全量或增量采集工控机,电脑文件或日志. 优势 开箱即用: 解压直接运行.不需额外下载.管理设备: 后台统一管理客户端.无人值守: 客户端自启动,自更新.稳定安全: 架构简单,兼容性好,通过授权控制访问. 架构 技术架构: Asp…

支持多种网络数据库格式的自动化转换工具——VisualXML

一、VisualXML软件介绍 对于DBC、ARXML……文件的编辑、修改等繁琐操作&#xff0c;WINDHILL风丘科技开发的总线设计工具——VisualXML&#xff0c;可轻松解决这一问题&#xff0c;提升工作效率。 VisualXML是一个强大且基于Excel表格生成多种网络数据库文件的转换工具&#…

四、OSG学习笔记-基础图元

前一章节&#xff1a; 三、OSG学习笔记-应用基础-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/145514021 代码&#xff1a;CuiQingCheng/OsgStudy - Gitee.com 一、绘制盒子模型 下面一个简单的 demo #include<windows.h> #include<osg/Node&…

window 安装GitLab服务器笔记

目录 视频&#xff1a; 资源&#xff1a; Linux CeneOS7&#xff1a; VMware&#xff1a; Linux无法安装 yum install vim -y 1.手动创建目录 2.下载repo PS 补充视频不可复制的代码 安装GitLab *修改root用户密码相关&#xff08;我卡在第一步就直接放弃了这个操作&…

MySQL数据库入门到大蛇尚硅谷宋红康老师笔记 基础篇 part 10

第10章_创建和管理表 DDL&#xff1a;数据定义语言。CREATE \ALTER\ DROP \RENAME TRUNCATE DML&#xff1a;数据操作语言。INSERT \DELETE \UPDATE \SELECT&#xff08;重中之重&#xff09; DCL&#xff1a;数据控制语言。COMMIT \…

前端如何判断浏览器 AdBlock/AdBlock Plus(最新版)广告屏蔽插件已开启拦截

2个月前AdBlock/AdBlock Plus疑似升级了一次 因为自己主要负责面对海外的用户项目&#xff0c;发现以前的检测AdBlock/AdBlock Plus开启状态方法已失效了&#xff0c;于是专门研究了一下。并尝试了很多方法。 已失效的老方法 // 定义一个检测 AdBlock 的函数 function chec…

html文件怎么转换成pdf文件,2025最新教程

将HTML文件转换成PDF文件&#xff0c;可以采取以下几种方法&#xff1a; 一、使用浏览器内置功能 打开HTML文件&#xff1a;在Chrome、Firefox、IE等浏览器中打开需要转换的HTML文件。打印对话框&#xff1a;按下CtrlP&#xff08;Windows&#xff09;或CommandP&#xff08;M…

科技查新过不了怎么办

“科技查新过不了怎么办&#xff1f;” “科技查新不通过的原因是什么&#xff1f;” 想必这些问题一直困扰着各位科研和学术的朋友们&#xff0c;尤其是对于查新经验不够多的小伙伴&#xff0c;在历经千难万险&#xff0c;从选择查新机构、填写线上委托单到付费&#xff0c;…

超详细的数据结构3(初阶C语言版)栈和队列。

文章目录 栈和队列1.栈1.1 概念与结构1.2 栈的实现 2. 队列2.1 概念与结构2.2 队列的实现 总结 栈和队列 1.栈 1.1 概念与结构 栈&#xff1a;⼀种特殊的线性表&#xff0c;其只允许在固定的⼀端进行插⼊和删除元素操作。进⾏数据插⼊和删除操作的⼀端称为栈顶&#xff0c;另…

centos 7 关于引用stdatomic.h的问题

问题&#xff1a;/tmp/tmp4usxmdso/main.c:6:23: fatal error: stdatomic.h: No such file or directory #include <stdatomic.h> 解决步骤&#xff1a; 1.这个错误是因为缺少C编译器的标准原子操作头文件 stdatomic.h。在Linux系统中&#xff0c;我们需要安装开发工具…

Unity WebGL包体压缩

最近在开发webgl&#xff0c;踩了很多坑&#xff0c;先来说下包体的问题。 开发完之后发现unity将文件都合并到一个文件了&#xff0c;一共有接近100m。 这对网页端的体验来说是可怕的&#xff0c;因为玩家必须要加载完所有的文件才能进入&#xff0c;这样体验特别差。 于是想…