要将“注册-登录-跳转页面”功能整合到已有的 main.c 工程中,只需按以下步骤操作,核心是复用 LVGL 和 SQLite 逻辑,并与现有工程的初始化流程对接:
步骤1:整理核心功能代码
将之前的功能拆分为 独立模块(方便嵌入),创建 2 个辅助文件:
• auth.h:声明注册登录相关函数
#ifndef AUTH_H
#define AUTH_H
#include "lvgl/lvgl.h"
#include "sqlite3.h"
// 外部声明(供main.c调用)
extern sqlite3 *db;
// 初始化数据库
int auth_db_init(void);
// 创建登录页面(在LVGL中显示)
void auth_create_login_page(void);
// 关闭数据库(程序退出时调用)
void auth_db_close(void);
#endif
• auth.c:实现注册登录、页面创建、数据库操作等逻辑auth.h(声明)
#include "auth.h"
#include
#include
// 全局变量(仅在auth模块内可见)
static lv_obj_t *login_page;
static lv_obj_t *username_entry;
static lv_obj_t *password_entry;
sqlite3 *db; // 外部可访问的数据库指针
// 登录成功页面
static void open_new_page(void) {
lv_obj_t *new_page = lv_obj_create(lv_scr_act());
lv_obj_set_size(new_page, 800, 480);
lv_obj_center(new_page);
lv_obj_t *label = lv_label_create(new_page);
lv_label_set_text(label, "登录成功!\n欢迎来到首页~");
lv_obj_set_style_text_font(label, &lv_font_montserrat_24, 0);
lv_obj_center(label);
// 返回按钮
lv_obj_t *back_btn = lv_btn_create(new_page);
lv_obj_set_size(back_btn, 150, 60);
lv_obj_align(back_btn, LV_ALIGN_BOTTOM_MID, 0, -50);
lv_obj_t *back_label = lv_label_create(back_btn);
lv_label_set_text(back_label, "返回登录");
lv_obj_set_style_text_font(back_label, &lv_font_montserrat_18, 0);
lv_obj_add_event_cb(back_btn, [](lv_event_t *e) {
lv_obj_del(lv_scr_act());
auth_create_login_page();
}, LV_EVENT_CLICKED, NULL);
}
// 注册按钮逻辑
static void register_btn_click(lv_event_t *e) {
const char *username = lv_textarea_get_text(username_entry);
const char *password = lv_textarea_get_text(password_entry);
if(strlen(username) == 0 || strlen(password) == 0) {
lv_obj_t *msg = lv_msgbox_create(lv_scr_act(), "错误", "账号或密码不能为空!", NULL, true);
lv_obj_set_style_text_font(lv_msgbox_get_text(msg), &lv_font_montserrat_18, 0);
lv_obj_center(msg);
return;
}
// 检查账号是否存在
sqlite3_stmt *stmt;
const char *check_sql = "SELECT username FROM users WHERE username = ?;";
if(sqlite3_prepare_v2(db, check_sql, -1, &stmt, NULL) != SQLITE_OK) {
lv_obj_t *msg = lv_msgbox_create(lv_scr_act(), "错误", sqlite3_errmsg(db), NULL, true);
lv_obj_center(msg);
return;
}
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
int exists = (sqlite3_step(stmt) == SQLITE_ROW) ? 1 : 0;
sqlite3_finalize(stmt);
if(exists) {
lv_obj_t *msg = lv_msgbox_create(lv_scr_act(), "提示", "账号已存在!", NULL, true);
lv_obj_center(msg);
return;
}
// 插入新用户
const char *insert_sql = "INSERT INTO users (username, password) VALUES (?, ?);";
if(sqlite3_prepare_v2(db, insert_sql, -1, &stmt, NULL) != SQLITE_OK) {
lv_obj_t *msg = lv_msgbox_create(lv_scr_act(), "错误", sqlite3_errmsg(db), NULL, true);
lv_obj_center(msg);
return;
}
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, password, -1, SQLITE_STATIC);
if(sqlite3_step(stmt) == SQLITE_DONE) {
lv_obj_t *msg = lv_msgbox_create(lv_scr_act(), "成功", "注册成功!", NULL, true);
lv_obj_center(msg);
lv_textarea_set_text(username_entry, "");
lv_textarea_set_text(password_entry, "");
}
sqlite3_finalize(stmt);
sqlite3_commit(db);
}
// 登录按钮逻辑
static void login_btn_click(lv_event_t *e) {
const char *username = lv_textarea_get_text(username_entry);
const char *password = lv_textarea_get_text(password_entry);
sqlite3_stmt *stmt;
const char *sql = "SELECT * FROM users WHERE username = ? AND password = ?;";
if(sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
lv_obj_t *msg = lv_msgbox_create(lv_scr_act(), "错误", sqlite3_errmsg(db), NULL, true);
lv_obj_center(msg);
return;
}
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, password, -1, SQLITE_STATIC);
int success = (sqlite3_step(stmt) == SQLITE_ROW) ? 1 : 0;
sqlite3_finalize(stmt);
if(success) {
lv_obj_del(login_page);
open_new_page();
} else {
lv_obj_t *msg = lv_msgbox_create(lv_scr_act(), "错误", "账号或密码错误!", NULL, true);
lv_obj_center(msg);
lv_textarea_set_text(password_entry, "");
}
}
// 创建登录页面(外部可调用)
void auth_create_login_page(void) {
login_page = lv_obj_create(lv_scr_act());
lv_obj_set_size(login_page, 800, 480);
lv_obj_clear_flag(login_page, LV_OBJ_FLAG_SCROLLABLE);
// 标题
lv_obj_t *title = lv_label_create(login_page);
lv_label_set_text(title, "用户登录");
lv_obj_set_style_text_font(title, &lv_font_montserrat_32, 0);
lv_obj_align(title, LV_ALIGN_TOP_MID, 0, 50);
// 账号输入
lv_obj_t *user_label = lv_label_create(login_page);
lv_label_set_text(user_label, "账号:");
lv_obj_set_style_text_font(user_label, &lv_font_montserrat_20, 0);
lv_obj_align(user_label, LV_ALIGN_TOP_MID, -150, 150);
username_entry = lv_textarea_create(login_page);
lv_obj_set_size(username_entry, 300, 50);
lv_obj_align_to(username_entry, user_label, LV_ALIGN_LEFT_MID, 80, 0);
lv_textarea_set_placeholder_text(username_entry, "请输入账号");
// 密码输入
lv_obj_t *pwd_label = lv_label_create(login_page);
lv_label_set_text(pwd_label, "密码:");
lv_obj_set_style_text_font(pwd_label, &lv_font_montserrat_20, 0);
lv_obj_align(pwd_label, LV_ALIGN_TOP_MID, -150, 230);
password_entry = lv_textarea_create(login_page);
lv_obj_set_size(password_entry, 300, 50);
lv_obj_align_to(password_entry, pwd_label, LV_ALIGN_LEFT_MID, 80, 0);
lv_textarea_set_placeholder_text(password_entry, "请输入密码");
lv_textarea_set_password_mode(password_entry, true);
// 注册按钮
lv_obj_t *reg_btn = lv_btn_create(login_page);
lv_obj_set_size(reg_btn, 150, 60);
lv_obj_align(reg_btn, LV_ALIGN_TOP_MID, -100, 320);
lv_obj_t *reg_label = lv_label_create(reg_btn);
lv_label_set_text(reg_label, "注册");
lv_obj_set_style_text_font(reg_label, &lv_font_montserrat_18, 0);
lv_obj_add_event_cb(reg_btn, register_btn_click, LV_EVENT_CLICKED, NULL);
// 登录按钮
lv_obj_t *login_btn = lv_btn_create(login_page);
lv_obj_set_size(login_btn, 150, 60);
lv_obj_align(login_btn, LV_ALIGN_TOP_MID, 100, 320);
lv_obj_t *login_label = lv_label_create(login_btn);
lv_label_set_text(login_label, "登录");
lv_obj_set_style_text_font(login_label, &lv_font_montserrat_18, 0);
lv_obj_add_event_cb(login_btn, login_btn_click, LV_EVENT_CLICKED, NULL);
}
// 初始化数据库(外部可调用)
int auth_db_init(void) {
if(sqlite3_open("user.db", &db) != SQLITE_OK) {
lv_log_error("数据库打开失败: %s", sqlite3_errmsg(db));
return 0;
}
const char *create_sql = "CREATE TABLE IF NOT EXISTS users ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"username TEXT UNIQUE NOT NULL,"
"password TEXT NOT NULL);";
char *err_msg = NULL;
if(sqlite3_exec(db, create_sql, NULL, NULL, &err_msg) != SQLITE_OK) {
lv_log_error("创建表失败: %s", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 0;
}
return 1;
}
// 关闭数据库(外部可调用)
void auth_db_close(void) {
if(db != NULL) {
sqlite3_close(db);
db = NULL;
}
}
步骤2:修改现有 main.c在现有工程的 main.c 中 引入模块并调用初始化函数,核心是在 LVGL 初始化后启动登录功能:
#include "lvgl/lvgl.h"
#include "auth.h" // 引入注册登录模块
// 其他现有头文件...
// 现有显示驱动和输入驱动(保持不变)
static void disp_init(void) {
// 你的显示驱动代码...
}
static void indev_init(void) {
// 你的输入驱动代码...
}
int main(void) {
// 1. 现有初始化(LVGL、显示、输入等)
lv_init();
disp_init();
indev_init();
// 2. 初始化注册登录功能
if(auth_db_init() != 1) {
// 数据库初始化失败处理(如打印错误并退出)
return 1;
}
// 3. 显示登录页面(替换或添加到现有页面流程)
auth_create_login_page();
// 4. 现有主循环(保持不变)
while(1) {
lv_timer_handler();
usleep(5000);
}
// 5. 程序退出时关闭数据库(如果主循环有退出逻辑)
auth_db_close();
return 0;
}
步骤3:修改编译配置
确保工程编译时 链接 LVGL 和 SQLite3 库,并包含新添加的 auth.c。
方法1:直接用 arm-linux-gcc 编译
在现有编译命令后添加 auth.c 和库依赖:
arm-linux-gnueabihf-gcc main.c auth.c -o your_project \
-I/path/to/lvgl/include -I/path/to/sqlite3/include \
-L/path/to/lvgl/build -L/path/to/sqlite3/lib \
-llvgl -lsqlite3 -lm -lpthread
方法2:修改 Makefile
在现有 Makefile 中添加 auth.c 源文件和依赖:
# 现有配置...
SRC = main.c auth.c # 添加auth.c
CFLAGS += -I/path/to/lvgl/include -I/path/to/sqlite3/include
LDFLAGS += -L/path/to/lvgl/build -L/path/to/sqlite3/lib
LIBS += -llvgl -lsqlite3 -lm -lpthread
# 其他现有规则...
关键注意事项
1. 页面冲突:如果现有工程已有默认页面,需在 main.c 中先删除原有页面(如 lv_obj_clean(lv_scr_act());),再调用 auth_create_login_page()。
2. 驱动兼容性:确保现有工程的 LVGL 显示驱动(disp_init)和输入驱动(indev_init)正常,登录页面依赖这些驱动工作。
3. 库版本:LVGL 版本需与代码兼容(建议 v8.x 或 v9.x),SQLite3 需为交叉编译的 ARM 版本。
4. 资源清理:若工程有退出逻辑,需调用 auth_db_close() 释放数据库资源。
通过以上步骤,即可将注册登录功能无缝整合到现有工程中,无需大幅修改原有代码。
没关系,我用最简单的方式告诉你怎么加——核心只需 3步,不用理解复杂逻辑,跟着做就行:
第一步:准备文件
把这3个文件放到你的工程文件夹里(和你的 main.c 放在一起):
1. 你的原有 main.c
2. 新建 auth.h(复制下面的代码)
3. 新建 auth.c(复制之前给的 auth.c 代码,不用改)auth.h 内容(直接复制):
#ifndef AUTH_H
#define AUTH_H
#include "lvgl/lvgl.h"
// 只需要记这3个函数,其他不用管
void auth_start(void); // 启动登录功能(在main里调用一次)
void auth_db_close(void); // 程序退出时关闭数据库(可选)
#endif
第二步:修改你的 main.c在你原有 main.c 里加3行代码,位置如下:
// 1. 在你原有的#include后面,加一行:
#include "auth.h"
// 2. 找到你的main函数,在LVGL初始化完成后,加一行启动登录功能:
int main(void) {
lv_init(); // 你原有的LVGL初始化
disp_init(); // 你原有的显示驱动初始化
indev_init(); // 你原有的触摸驱动初始化
// 【新增这一行】启动登录页面
auth_start();
// 你的主循环(保持不变)
while(1) {
lv_timer_handler();
usleep(5000);
}
// 【可选】如果你的程序有退出逻辑,加这一行关闭数据库
auth_db_close();
return 0;
}
第三步:修改 auth.c(只改1处)
在 auth.c 最后,加一个 auth_start 函数(用来给 main.c 调用):
// 加在auth.c的最下面
void auth_start(void) {
// 初始化数据库并显示登录页面
if(auth_db_init() == 1) {
auth_create_login_page();
}
}
总结:你只需要关心这3个点
1. 把 auth.h 和 auth.c 放进工程文件夹。
2. 在 main.c 里 #include "auth.h"。
3. 在 main 函数的 LVGL 初始化后,加一行 auth_start();。
这样编译后,程序启动就会直接显示登录页面,原来的功能不会受影响(如果有冲突,只需要在 auth_start(); 之前关闭原有页面即可)。
编译时记得把 auth.c 一起编译,比如:
arm-linux-gcc main.c auth.c -o 程序名 原来的编译参数 -lsqlite3