更新SD卡文件列表到tablew中的list

#include"SD.h"#include"ff.h"#include"usart.h"#include<string.h>#include"lvgl.h"#include<stdio.h>// 全局 FatFs 对象和文件操作变量 FATFS fs;/* FatFs 文件系统对象 */ FIL fil;/* 文件对象 */ FRESULT fres;/* FatFs 函数返回结果 */// 文件列表存储char file_list[MAX_FILES][MAX_NAME_LEN];int file_count =0;// 打印文件信息(内部使用)staticvoidprint_file_info(FILINFO* fno);voidList_SD_Files(void){ DIR dir; FILINFO fno; UINT i =0;char path[]="0:";// 挂载文件系统 fres =f_mount(&fs, path,1);if(fres != FR_OK){HAL_UART_Transmit(&huart1,(uint8_t*)"failed",6,1000);return;}HAL_UART_Transmit(&huart1,(uint8_t*)"successful",10,1000);HAL_UART_Transmit(&huart1,(uint8_t*)"\r\n",2,1000);// 打开根目录 fres =f_opendir(&dir, path);if(fres != FR_OK){HAL_UART_Transmit(&huart1,(uint8_t*)"failedFF",8,1000);return;}// 读取目录项while(1){ fres =f_readdir(&dir,&fno);if(fres != FR_OK || fno.fname[0]==0)break;if(strcmp(fno.fname,".")==0||strcmp(fno.fname,"..")==0)continue;print_file_info(&fno);}// 清理资源f_closedir(&dir);f_mount(NULL, path,0);}staticvoidprint_file_info(FILINFO* fno){// 打印文件名HAL_UART_Transmit(&huart1,(uint8_t*)fno->fname,strlen(fno->fname),1000);strncpy(file_list[file_count], fno->fname, MAX_NAME_LEN -1); file_list[file_count][MAX_NAME_LEN -1]='\0'; file_count++;HAL_UART_Transmit(&huart1,(uint8_t*)"\r\n",2,1000);}intSD_ReadFile(char* flname){char path[]="0:";char line[100];// 挂载文件系统 fres =f_mount(&fs, path,1);if(fres != FR_OK)return(int)fres;// 打开文件 fres =f_open(&fil, flname, FA_READ);if(fres != FR_OK){f_mount(NULL, path,0);return(int)fres;}// 逐行读取while(f_gets(line,sizeof(line),&fil)){HAL_UART_Transmit(&huart1,(uint8_t*)line,strlen(line),1000);HAL_UART_Transmit(&huart1,(uint8_t*)"\r\n",2,1000);}// 关闭文件并卸载f_close(&fil);f_mount(NULL, path,0);return(int)fres;}intSD_WriteFile(char* newfname,char* data, UINT* bw){char path[]="0:"; UINT len =strlen(data);// 挂载文件系统 fres =f_mount(&fs, path,1);if(fres != FR_OK)return(int)fres;// 创建/打开文件 fres =f_open(&fil, newfname, FA_CREATE_ALWAYS | FA_WRITE | FA_READ);if(fres != FR_OK){f_mount(NULL, path,0);return(int)fres;}// 写入数据 fres =f_write(&fil, data, len, bw);if(fres == FR_OK){HAL_UART_Transmit(&huart1,(uint8_t*)"Write successful",16,1000);HAL_UART_Transmit(&huart1,(uint8_t*)"\r\n",2,1000);}else{HAL_UART_Transmit(&huart1,(uint8_t*)"Write failed",12,1000);HAL_UART_Transmit(&huart1,(uint8_t*)"\r\n",2,1000);}// 刷新并关闭f_sync(&fil);f_close(&fil);f_mount(NULL, path,0);return(int)fres;}// 将SD卡文件列表更新到LVGL界面 - 仅显示文件名voidUpdate_SD_Files_To_LVGL(lv_obj_t* tab_page){if(tab_page ==NULL){//HAL_UART_Transmit(&huart1, (uint8_t*)"Tab page is NULL\r\n", 18, 1000);return;}// 清除tab页面中的所有子对象lv_obj_clean(tab_page);// 为每个文件创建标签(只显示文件名)for(int i =1; i < file_count && i < MAX_FILES; i++){lv_obj_t* file_label =lv_label_create(tab_page);lv_label_set_text(file_label, file_list[i]);// 设置样式:文件名使用等宽字体lv_obj_set_style_text_font(file_label,&lv_font_montserrat_14,0);lv_obj_set_style_text_color(file_label,lv_color_hex(0x000000),0);// 垂直排列,每行间隔25像素lv_obj_align(file_label, LV_ALIGN_TOP_LEFT,10,10+(i *25));}// 如果没有文件,显示提示信息if(file_count ==0){lv_obj_t* no_file_label =lv_label_create(tab_page);lv_label_set_text(no_file_label,"No files found");lv_obj_set_style_text_color(no_file_label,lv_color_hex(0x888888),0);lv_obj_align(no_file_label, LV_ALIGN_CENTER,0,0);}//HAL_UART_Transmit(&huart1, (uint8_t*)"Files displayed on LVGL (only filenames)\r\n", 42, 1000);}

.h

#ifndefFATFS_UTIL_H#defineFATFS_UTIL_H#include"ff.h"#include"main.h"#include"lvgl.h"#defineMAX_FILES500// 最大文件数#defineMAX_NAME_LEN50// 文件名最大长度(包含 '\0')externchar file_list[MAX_FILES][MAX_NAME_LEN];externint file_count;voidList_SD_Files(void);intSD_ReadFile(char* flname);intSD_WriteFile(char* newfname,char* data, UINT* bw);// LVGL界面更新函数voidUpdate_SD_Files_To_LVGL(lv_obj_t* tabview);#endif/* FATFS_UTIL_H */

调用List_SD_Files()后调用Update_SD_Files_To_LVGL(guider_ui.screen_1_list_1);即可显示,传入要传入的图框

Read more

Qt 前后端通信(QWebChannel Js / C++ 互操作):原理、示例、步骤解说

Qt 前后端通信(QWebChannel Js / C++ 互操作):原理、示例、步骤解说

Qt 提供的 QWebEngineView 是一个基于 Chromium 内核的浏览器组件,通过它,开发者可以使用 HTML、CSS、JavaScript 等技术开发 Web 页面并呈现在 Qt 桌面应用中,但与开发纯 Web 页面不同的是,这些页面通常需要和 应用中的其他组件交互,例如获取后端数据进行渲染、将前端用户指令传达给后端执行等,这将不可避免地涉及到前端 Js 和 后端 C++ 之间的交互问题,而 Qt 为此给出的解决方案就是 QWebChannel,通过 QWebChannel 前端 Web 页面和与后端 C++ 程序实现自然而顺畅的交互,甚至前后端的操作风格都极为一致。本文我们将细致地介绍QWebChannel 前后端交互的原理,通过四个详实的示例程序讲解每一步重要的操作步骤,通过本文,你将对 QWebChannel 有一个全面而深入的了解。 1. 工作原理

前端状态管理:别让你的状态变成一团乱麻

前端状态管理:别让你的状态变成一团乱麻 毒舌时刻 这状态管理得跟蜘蛛网似的,谁能理得清? 各位前端同行,咱们今天聊聊前端状态管理。别告诉我你还在使用 setState 管理所有状态,那感觉就像在没有地图的情况下寻宝——能找,但累死你。 为什么你需要状态管理 最近看到一个项目,组件之间传递状态需要经过 5 层,修改一个状态要修改多个地方。我就想问:你是在做状态管理还是在做传递游戏? 反面教材 // 反面教材:混乱的状态管理 function App() { const [user, setUser] = useState(null); const [posts, setPosts] = useState([]); const [comments, setComments] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { async function fetchData() { setLoading(

openclaw喂饭教程!在 Linux 环境下快速完成安装、初始化与 Web UI 配置

openclaw喂饭教程!在 Linux 环境下快速完成安装、初始化与 Web UI 配置

前言 OpenClaw 是一款开源的 AI Agent 工具,但对第一次接触的用户来说,完整跑通流程并不直观。本文以 Linux 环境为例,详细记录了 OpenClaw 的安装、初始化流程、模型选择、TUI 使用方式,以及 TUI 与 Web UI 认证不一致导致的常见问题与解决方法,帮助你最快速度把 OpenClaw 真正跑起来 环境准备 1)安装nodejs curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo apt install -y nodejs > node

实战演练:基于快马平台快速构建一个支持tokenp钱包登录的DApp前端

今天想和大家分享一个实战项目:如何快速构建一个支持TokenP钱包登录的DApp前端。这个项目特别适合想学习Web3开发的初学者,整个过程在InsCode(快马)平台上完成,省去了本地环境配置的麻烦。 1. 项目准备 首先需要明确几个核心功能:钱包连接、用户信息展示、链上数据查询和退出登录。选择Next.js框架是因为它既支持服务端渲染,又能很好地与各种Web3库集成。Wagmi和Viem这两个库是目前最流行的以太坊开发工具组合,能大大简化钱包交互流程。 2. 钱包连接实现 在首页添加"使用钱包登录"按钮后,通过Wagmi提供的useConnect钩子就能轻松实现钱包连接功能。这里需要注意处理用户拒绝连接的情况,以及不同钱包提供商的兼容性问题。TokenP钱包作为移动端主流钱包,通过WalletConnect协议可以很好地与网页应用交互。 3. 用户信息展示 连接成功后,使用Wagmi的useAccount钩子获取用户的钱包地址。为了提升用户体验,我做了地址缩写处理(显示前4位和后4位),并在页面顶部显示欢迎信息。这里还添加了一个复制地址的小功能,方便用户操作。 4. 链上数