LVGL:根据队列信息创建子容器


#include "lvgl.h"
#include <windows.h>
#include <stdbool.h>
#include <stdio.h>

// 定义子容器属性结构体
typedef struct {
    bool is_sender;       // 标记是否为发送方容器
    int16_t pos_x;        // 在X轴上的位置
    int16_t pos_y;        // 在Y轴上的位置
    uint16_t width;       // 容器宽度
    uint16_t height;      // 容器高度
} sub_container_attr_t;

// 全局变量声明
static volatile bool is_scrolling = false; // 滚动状态标记
static lv_obj_t* main_container = NULL; // 主容器对象指针
HANDLE lvgl_mutex = NULL; // 互斥锁句柄,用于线程同步
HANDLE queue_not_empty_event = NULL; // 事件句柄,用于通知队列不为空

// 队列结构定义,包含子容器属性、音频数据等
#define QUEUE_CAPACITY 50
typedef struct {
    sub_container_attr_t data[QUEUE_CAPACITY]; // 子容器属性数组
    unsigned char audioBuffer[1024]; // 音频数据缓冲区
    unsigned char audioPlayer; // 音频播放控制标志
    unsigned char audioRecorder; // 录音控制标志
    unsigned char audioData; // 音频相关数据
    int head; // 队头索引
    int tail; // 队尾索引
    int count; // 队列中元素数量
} queue_t;

// 初始化队列
void init_queue(queue_t* q) {
    q->head = q->tail = q->count = 0;
}

// 判断队列是否为空
bool is_queue_empty(queue_t* q) {
    return q->count == 0;
}

// 向队列中添加元素
void enqueue(queue_t* q, sub_container_attr_t item) {
    if (q->count == QUEUE_CAPACITY) return; // 队列满则不执行入队
    q->data[q->tail] = item;
    q->tail = (q->tail + 1) % QUEUE_CAPACITY;
    q->count++;
    SetEvent(queue_not_empty_event); // 设置事件,表明队列非空
}

// 从队列中移除并返回头部元素
bool dequeue(queue_t* q, sub_container_attr_t* item) {
    if (q->count == 0) return false; // 队列空则返回false
    *item = q->data[q->head];
    q->head = (q->head + 1) % QUEUE_CAPACITY;
    q->count--;
    return true;
}

// 滚动事件处理回调函数
void on_scroll_event(lv_event_t* e) {
    lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_SCROLL_BEGIN) is_scrolling = true;
    else if (code == LV_EVENT_SCROLL_END) is_scrolling = false;
}

// 初始化LVGL库及创建主容器
void initialize_lvgl_and_container() {
    lv_init(); // 初始化LVGL库
    lv_obj_t* screen = lv_obj_create(NULL); // 创建屏幕对象
    if (screen == NULL) { printf("屏幕对象创建失败\n"); return; }
    lv_scr_load(screen); // 加载屏幕

    main_container = lv_obj_create(screen); // 创建主容器
    if (main_container == NULL) { printf("主容器创建失败\n"); return; }
    lv_obj_set_size(main_container, 800, 400); // 设置大小
    lv_obj_align(main_container, LV_ALIGN_CENTER, 0, 0); // 居中对齐

    // 设置滚动条并添加滚动事件处理
    lv_obj_set_scrollbar_mode(main_container, LV_SCROLLBAR_MODE_AUTO);
    lv_obj_add_event_cb(main_container, on_scroll_event, LV_EVENT_ALL, NULL);
}

// 根据队列信息创建子容器
void create_sub_container(queue_t* q) {
    while (true) {
        WaitForSingleObject(lvgl_mutex, INFINITE);
        if (is_queue_empty(q)) {
            ReleaseMutex(lvgl_mutex);
            WaitForSingleObject(queue_not_empty_event, INFINITE);
            continue;
        }

        sub_container_attr_t item;
        if (dequeue(q, &item)) {
            lv_obj_t* sub_cont = lv_obj_create(main_container);
            if (sub_cont == NULL) { printf("子容器创建失败\n"); ReleaseMutex(lvgl_mutex); return; }

            lv_obj_set_pos(sub_cont, item.pos_x, item.pos_y);
            lv_obj_set_size(sub_cont, item.width, item.height);

            lv_obj_t* label = lv_label_create(sub_cont);
            //lv_label_set_text(label, item.is_sender ? "发送方消息" : "接收方消息");
            lv_label_set_text(label, item.is_sender ? "Sender Message" : "Receiver Message");

            ReleaseMutex(lvgl_mutex);
            break;
        }
        else {
            ReleaseMutex(lvgl_mutex);
        }
    }
}

// 修改后的生产消息函数,变为无终止循环,每次调用产生一个消息
void produce_single_message(queue_t* q, bool* isSending) {
    static int counter = 0;
    sub_container_attr_t new_item;

    // 交替决定是发送还是接收消息
    if (*isSending) {
        new_item.is_sender = true;
        new_item.pos_x = 10;
        printf("发送方消息加入队列\n");
    }
    else {
        new_item.is_sender = false;
        new_item.pos_x = 790 - 200 - 50;
        printf("接收方消息加入队列\n");
    }
    new_item.pos_y = counter * 50 + 10;
    new_item.width = 200;
    new_item.height = 50;

    enqueue(q, new_item);
    counter = (counter + 1) % 200; // 计数循环回0,模拟循环发送200个消息
    *isSending = !*isSending; // 交替发送/接收标志
}

// 更新ui_thread_func以包含produce_single_message调用
DWORD WINAPI ui_thread_func(LPVOID lpParam) {
    initialize_lvgl_and_container();
    lvgl_mutex = CreateMutex(NULL, FALSE, NULL);
    queue_not_empty_event = CreateEvent(NULL, FALSE, FALSE, NULL);

    queue_t message_queue;
    init_queue(&message_queue);

    bool isSending = true; // 初始化发送方回合标志

    while (1) {
        if (!is_scrolling) lv_task_handler();
        Sleep(100); // UI线程的常规处理等待

        // 每100毫秒检查一次是否需要生产消息
        if (isSending) {
            produce_single_message(&message_queue, &isSending); // 发送方消息
            Sleep(100); // 确保发送和接收之间有时间差
        }
        else {
            produce_single_message(&message_queue, &isSending); // 接收方消息
            Sleep(200); // 等待更长时间模拟接收间隔
        }

        // create_sub_container函数调用逻辑不变
        create_sub_container(&message_queue);
    }

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值