基于LVGL的自动贩卖机系统-GEC6818开发板

一、参考

        1、LVGL移植到ARM开发板(GEC6818开发板)_6818 lvgl-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/wwwqqq2014/article/details/136690316?spm=1001.2014.3001.5502        2、基于GEC6818开发板实现自动贩卖机(C语言 + lvgl库 + 系统编程 + 网络编程 + sqlite3数据库)_使用lvgl图形库开发一款基于linux操作系统的自动售卖机软件-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_74143852/article/details/133494058        3、LVGL不同版本的百问网

快捷选择版本:

注意!本系统使用的是LVGL8.2版本,不同版本的LVGL里的函数名可能相同,但传入的参数会不同,所以要看清楚自己用的是什么版本的LVGL,再去其对应的百问网查看控件如何使用,不然用错就会懵逼,很难搞哦。

二、框架

1.功能

客户端 
        1、商品浏览
        2、商品选择
        3、商品搜索
        4、商品购买(点击图片模拟支付)
服务端
        1、储存购买信息
        2、提醒补货
        3、添加新商品

2.网络编程

        1、商品信息文件由本地文件提供,生成商品信息文件后将其存入开发板中

        商品信息文件生成代码

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

//货物信息结构体
struct link_node
{
    char jpgpath[128];                  //存放图片路径名
    char cname[64];                     //中文商品名
    char name[32];                      //英文商品名
    float price;                        //商品价格
    int number;                         //商品数量
};

//结构体初始化
struct link_node *request_link_node(void)
{
    struct link_node *new_node;

    new_node = malloc(sizeof(struct link_node));//申请内存
    if(new_node == NULL)                        //判断链表节点是否申请成功
    {
        perror("申请节点失败\n");
        return NULL;
    }

    return new_node;
}

int main(void)
{
    struct link_node *new_node;
    new_node = request_link_node();
    char buff[1024]={0};

    FILE *fp;

    fp = fopen("goods.txt", "w+");
    if(fp == NULL)
    {
        perror("open fail");
        return -1;
    }

    while(1)
    {
        printf("input jpgpath:\n");
        scanf("%s", new_node->jpgpath);
        printf("input cname:\n");
        scanf("%s", new_node->cname);
        printf("input name:\n");
        scanf("%s", new_node->name);
        printf("input price:\n");
        scanf("%f", &new_node->price);
        printf("input number:\n");
        scanf("%d", &new_node->number);
        
        fprintf(fp, "%s %s %s %f %d\n", new_node->jpgpath, new_node->cname, new_node->name, new_node->price, new_node->number);
        printf("determine?\n");
        scanf("%s", buff);
        if(strcmp(buff, "exit")==0)
        {
            break;
        }
    }

    fclose(fp);

    return 0;
}


        2、虚拟机为服务器,6818开发板为客户端

        服务器代码

//服务端
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

struct all_info
{
    char type;          //消息类型
    char cname[64];     //商品中文名
    int number;         //购买的商品数量
    float price;        //总价格
    char payment[64];   //支付方式
};

struct link_node
{
    char jpgpath[128];                  //存放图片路径名
    char cname[64];                     //中文商品名
    char name[32];                      //英文商品名
    float price;                        //商品价格
    int number;                         //商品数量
};



void *send_data(void *arg)
{
    
    int sockfd = *((int*)arg);
    int cmd, ret;
    char send_buff[1024]={0};
    struct link_node *new_node;
    new_node = malloc(sizeof(struct link_node));

    while(1)
    {
        printf("输入1进行添加新商品\n");
        scanf("%d", &cmd);
        memset(send_buff, 0, sizeof(send_buff));
        switch(cmd)
        {
        case 1:
            printf("input jpgpath:\n");
            scanf("%s", new_node->jpgpath);
            printf("input cname:\n");
            scanf("%s", new_node->cname);
            printf("input name:\n");
            scanf("%s", new_node->name);
            printf("input price:\n");
            scanf("%f", &new_node->price);
            printf("input number:\n");
            scanf("%d", &new_node->number);

            sprintf(send_buff, "%s %s %s %f %d\n", new_node->jpgpath, new_node->cname, new_node->name, new_node->price, new_node->number);

            ret = send(sockfd, send_buff, sizeof(send_buff), 0);
            break;
        
        default:
            break;
        }
        printf("\n");
        while (getchar() != '\n');
    }
    
}


int main(void)
{
    time_t time;
    int sockfd;
    int ret;
    char recv_buff[256] = {0}; 

    //获取时间结构体
    struct timeval tv;
    struct tm* ptm;
    char time_string[40];

    //定义获取全部信息结构体
    struct all_info *goods_info;
    goods_info = malloc(sizeof(struct all_info));

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd == -1)
    {
        printf("sockfd fail\n");
        return -1;
    }

    //所以设置端口号可以复用,这两条语句放在 绑定bind 之前
    int optval = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,&optval, sizeof(optval));

    //服务端信息设置
    struct sockaddr_in serverAddr;//服务端
    serverAddr.sin_family = AF_INET;//地址族 IPV4协议
    serverAddr.sin_port = htons(50000);//主机端口号转成网络端口号
    serverAddr.sin_addr.s_addr = inet_addr("192.168.7.212");//主机ip转换为网络ip

    ret = bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr_in));//绑定自己的ip与端口
    if(ret == -1)
    {
        printf("bind fail\n");
        return -1;
    }
    ret = listen(sockfd, 5);//监听,设置最多连接的客户端总数
    if(ret == -1)
    {
        printf("listen fail\n");
        return -1;
    }

    //客户端信息设置
    struct sockaddr_in clientAddr;//客户端

    int len = sizeof(struct sockaddr_in);

    int newCentfd = accept(sockfd, (struct sockaddr *)&clientAddr, &len);//等待客户端连接
    if(newCentfd == -1)
    {
        printf("accept fail\n");
        return -1;
    }
    
    //设置线程
    pthread_t thread;
    //设置线程分离属性
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    //创建线程,接受数据
    pthread_create(&thread, &attr, send_data, &newCentfd);

    //打印客户端ip与端口号
    printf("客户端ip:%s,端口号:%d\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));

    while(1)
    {
        //接收客户端的数据
        ret = recv(newCentfd, recv_buff, sizeof(recv_buff), 0);
        if(ret == -1)
        {
            printf("recv fail\n");
            return -1;
        }
        if(ret == 0)
        {
            printf("客户端已经断开\n");
            break;
        }

        //读取一个字节,实际读取的是消息类型
        strncpy(&goods_info->type, recv_buff, 1);
        

        //如何消息类型为1时,为购买信息,将购买信息存到文件中
        if(strcmp(&goods_info->type, "1") == 0)
        {
            //将接收的数据进行拆分
            sscanf(recv_buff, "%c %s %d %f %s", &goods_info->type, goods_info->cname, &goods_info->number, &goods_info->price, goods_info->payment);
            
            memset(recv_buff, 0, sizeof(recv_buff));

            sprintf(recv_buff, "购买%s,总数%d,总金额%.1f元,%s", goods_info->cname, goods_info->number, goods_info->price, goods_info->payment);
            

            //获取时间
            gettimeofday(&tv, NULL);
            ptm = localtime (&(tv.tv_sec));
            strftime (time_string, sizeof(time_string), "%Y-%m-%d", ptm);//输出格式为: 2003-03-03

            //将购买信息存到文件中
            FILE *fp;
            fp = fopen("payment.txt", "a");
            if(fp == NULL)
            {
                perror("open fail");
                return -1;
            }
            fprintf(fp, "%s %s\n", time_string, recv_buff);
            fclose(fp);
            memset(goods_info, 0, sizeof(struct all_info));
            memset(time_string, 0, sizeof(time_string));
        }

        //如何消息类型为2时,为商品缺货信息
        if(strcmp(&goods_info->type, "2") == 0)
        {   
            sscanf(recv_buff, "%c %s", &goods_info->type, goods_info->cname);
            memset(recv_buff, 0, sizeof(recv_buff));
            sprintf(recv_buff, "%s已售完,请进行补货", goods_info->cname);
            printf("sell:%s\n", recv_buff);
            memset(goods_info, 0, sizeof(struct all_info));
        }

        usleep(100);
        memset(recv_buff, 0, sizeof(recv_buff));
    }

    close(newCentfd);
    close(sockfd);
    return 0;
}

三、主代码

#include <stdio.h>
#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "lv_drivers/display/fbdev.h"
#include "lv_drivers/indev/evdev.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

//#include "lv_gui_password_keyboard.h"

#define DISP_BUF_SIZE (480 * 800)
#define LOGIN_USER1			"mocly"	//用户名
#define LOGIN_USER2			"MOCLY"
#define LOGIN_PASSWORD	   "123"	//密码

struct sockaddr_in serverAddr;//服务器
struct sockaddr_in clientAddr;//客户端
int sockfd;
char *wepay = "使用微信付款";
char *apay = "使用支付宝付款";
static const char * btns[] ={"关闭", ""}; //消息框关闭的按钮
lv_obj_t * usern;//用户名框
lv_obj_t * passw;//密码框
lv_obj_t * search;//搜索框
lv_obj_t * change_price_textarea;

//char *path[]={"S:/mdata/project/picture/fenda.jpg","S:/mdata/project/picture/xuebi.jpg","S:/mdata/project/picture/kele.jpg","S:/mdata/project/picture/shupian.jpg","S:/mdata/project/picture/mozhua.jpg","S:/mdata/project/picture/chapai.jpg","S:/mdata/project/picture/maidong.jpg"};
struct link_node *head;

void lvgl_tab(lv_event_t * e);
static void lvgl_tab_event(lv_event_t * e);
static void ta_event_cb(lv_event_t * e);
static void Root_login(lv_event_t * e);
void decide_buy(lv_event_t * e);
void goods_info(void);
void root_goods(lv_event_t * e);
static void login_btn_event_cb( lv_event_t * e);
void goods_add(lv_event_t * e);
void goods_redu(lv_event_t * e);
void goods_Choose(lv_event_t * e);
void Advertisement(void);
void manage_goods(lv_event_t *e);
void manage_add(lv_event_t *e);
void manage_redu(lv_event_t *e);
void wechat_success(lv_event_t * e);
void alipay_success(lv_event_t * e);
void search_box(void);
void search_goods(lv_event_t * e);
void goods_search_Choose(struct link_node *node);
void chack_search(lv_event_t * e);
void enter_change(lv_event_t * e);
void change_price(lv_event_t * e);
void update_goods(lv_event_t * e);
void delete_goods(lv_event_t * e);
void *recv_data(void *arg);

//节点结构体
struct link_node
{
    char jpgpath[128];                  //存放图片路径名
    char cname[64];                     //中文商品名
    char name[32];                      //英文商品名
    float price;                        //商品价格
    int number;                         //商品数量

    struct link_node *next;             //用来存放下一个节点
    struct link_node *prve;             //用来存放上一个节点
};

//大结构体存放一个商品信息的节点与购买的数量
struct buy_info
{
    struct link_node *node;//商品节点
    int sum_goods; //总购买数量
};

//申请一个新的节点
struct link_node *request_link_node(void)
{
    struct link_node *new_node;

    new_node = malloc(sizeof(struct link_node));//申请内存
    if(new_node == NULL)                        //判断链表节点是否申请成功
    {
        perror("申请节点失败\n");
        return NULL;
    }

    new_node->next = new_node;
    new_node->prve = new_node; 

    return new_node;
}

//插入到指定节点的前面
void insert_node_to_list_tail(struct link_node *head, struct link_node *node)
{
    node->prve = head->prve; 
    node->next = head;

    head->prve->next = node;
    head->prve = node;
}

//删除节点
int remove_link_node(struct link_node *head_node, struct link_node *del_node)
{
    struct link_node *pos, *npos;
    
    for(pos=head_node, npos=pos->next; npos != head_node; pos=npos, npos=npos->next)
    {
        if(strcmp(npos->name, del_node->name)==0)
        {
            pos->next = npos->next;
            npos->next->prve = pos;
            
            npos->next = npos;
            npos->prve = npos;
            break;
        }
    }
    
    free(npos);
    return 0;
}


//商品链表信息存储初始化
void goods_info(void)
{
    int c;
    struct link_node *new_node;
    new_node = request_link_node();
    FILE *fp;
    fp = fopen("goods.txt", "r");
    if(fp == NULL)
    {
        perror("open fail");
        return;
    }
    while(1)
    {
        new_node = request_link_node();
        if(c == EOF && feof(fp))
        {
            break;
        }
        fscanf(fp, "%s %s %s %f %d", new_node->jpgpath, new_node->cname, new_node->name, &new_node->price, &new_node->number);
        
        c = fgetc(fp);
        if(c == EOF && feof(fp))
        {
            break;
        }
        
        insert_node_to_list_tail(head, new_node);
    }

    fclose(fp);
}

/*管理员登录有关函数*/
//键盘回调函数
static void ta_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * ta = lv_event_get_target(e);
    lv_obj_t * kb = lv_event_get_user_data(e);
    if(code == LV_EVENT_FOCUSED) {
        lv_keyboard_set_textarea(kb, ta);
        lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
    }

    if(code == LV_EVENT_DEFOCUSED) {
        lv_keyboard_set_textarea(kb, NULL);
        lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
    }
}

//删除商品
void delete_goods(lv_event_t * e)
{
    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    struct link_node *del_node, *p;
    del_node = e->user_data;

    remove_link_node(head, del_node);

    FILE *fp;
    fp = fopen("goods.txt", "w+");
    if(fp == NULL)
    {
        perror("open fail");
        return;
    }

    p = head->next;

    for(p; p != head; p = p->next)
    {
        fprintf(fp, "%s %s %s %f %d\n", p->jpgpath, p->cname, p->name, p->price, p->number);
    }

    fclose(fp);

    //删除成功消息框
    lv_obj_t * deletebox = lv_msgbox_create(lv_scr_act(), "下架", "下架成功", btns, false);
    lv_obj_add_style(deletebox, &style1, 0);
    lv_obj_add_event_cb(deletebox, root_goods, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_center(deletebox);

}

//更新商品信息,将信息存入文件
void update_goods(lv_event_t * e)
{
    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    FILE *fp;
    fp = fopen("goods.txt", "w+");
    if(fp == NULL)
    {
        perror("open fail");
        return;
    }

    struct link_node *p;
    p = head->next;

    //遍历链表,将数据存入文件
    for(p; p != head; p = p->next)
    {
        fprintf(fp, "%s %s %s %f %d\n", p->jpgpath, p->cname, p->name, p->price, p->number);
    }

    printf("update success\n");

    fclose(fp);
    
    //消息弹窗
    lv_obj_t * updatebox2 = lv_msgbox_create(lv_scr_act(), "更新商品", "更新商品信息成功", btns, false);
    lv_obj_add_style(updatebox2, &style1, 0);
    lv_obj_add_event_cb(updatebox2, root_goods, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_center(updatebox2);

}

//确认修改价格
void enter_change(lv_event_t * e)
{
    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    struct link_node *p;
    p = e->user_data;
    float new;
    char *pEnd;
    const char * new_price = lv_textarea_get_text(change_price_textarea);//获取价格

    new = strtod(new_price, pEnd);
    p->price = new;
    lv_obj_t * changebox1 = lv_msgbox_create(lv_scr_act(), "更改价格", "更改商品价格成功", btns, false);
    lv_obj_add_style(changebox1, &style1, 0);
    lv_obj_add_event_cb(changebox1, root_goods, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_center(changebox1);

}

//修改商品价格
void change_price(lv_event_t * e)
{
    struct link_node *p;
    p = e->user_data;
    
    lv_obj_clean(lv_scr_act()); // 清理屏幕

    lv_obj_t * srg = lv_obj_create(lv_scr_act());
    lv_obj_set_style_bg_color(srg, lv_color_hex(0xFFFFFF), 0);//白色
    lv_obj_set_size(srg, 800, 480);
    lv_obj_set_pos(srg, 0, 0);

    //键盘
    lv_obj_t * changekb = lv_keyboard_create(lv_scr_act());
    lv_keyboard_set_mode(changekb, LV_KEYBOARD_MODE_NUMBER);//设为数字模式
    //创建修改文本框
    change_price_textarea = lv_textarea_create(lv_scr_act());
    lv_obj_align(change_price_textarea, LV_ALIGN_CENTER, 0, -90);
    lv_obj_add_event_cb(change_price_textarea, ta_event_cb, LV_EVENT_ALL, changekb);
    lv_textarea_set_placeholder_text(change_price_textarea, "price");
    lv_textarea_set_one_line(change_price_textarea, true);//设置单行模式
    lv_obj_set_size(change_price_textarea, 200, 50);

    //确认按钮
    lv_obj_t * change_price_btn =  lv_btn_create(lv_scr_act());
    lv_obj_set_size(change_price_btn, 80, 80);
    lv_obj_align(change_price_btn, LV_ALIGN_CENTER, 150, -90);
    lv_obj_t * change_price_label = lv_label_create(change_price_btn);
    lv_label_set_text(change_price_label, "enter");
    lv_obj_align(change_price_label, LV_ALIGN_CENTER, 0, 0);

    //返回按钮
    lv_obj_t * btn_back = lv_btn_create(lv_scr_act());//返回
    lv_obj_set_size(btn_back, 60, 50);
    lv_obj_align(btn_back, LV_ALIGN_TOP_LEFT, 0, 0);
    lv_obj_t * back_label = lv_label_create(btn_back);
    lv_obj_align(back_label, LV_ALIGN_CENTER, 0, 0);
    lv_label_set_text(back_label, "back");

    //回调函数
    lv_obj_add_event_cb(btn_back, manage_goods, LV_EVENT_SHORT_CLICKED, p);//返回
    lv_obj_add_event_cb(change_price_btn, enter_change, LV_EVENT_SHORT_CLICKED, p);//确认购买
}

//管理员加商品
void manage_add(lv_event_t *e)
{
    struct link_node *p;
    p = e->user_data;
    p->number++;

    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    lv_obj_clean(lv_scr_act()); // 清理屏幕

    /*选项卡列表*/
    lv_obj_t * tabview;
    tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 0);//创建选项卡并规定标签方向(为顶部)
    lv_obj_set_size(tabview, 800, 480); // 设置选项卡列表的大小
    lv_obj_set_pos(tabview, 0, 0);
    lv_obj_set_style_bg_color(tabview, lv_color_hex(0xFFFFFF), 0); //背景颜色

    //加一个选项卡标签Tab1,不显示
    lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Welcome!");

    //定义一个部件,在部件里显示图片,按钮等
    lv_obj_t * temp = lv_obj_create(tab1);
    lv_obj_set_size(temp, 350, 350);
    lv_obj_set_style_bg_color(temp, lv_color_hex(0xFFAC2B), 0);
    lv_obj_align(temp, LV_ALIGN_CENTER, 0, 0);

    //修改商品价格按钮
    lv_obj_t * change_price_btn =  lv_btn_create(tab1);
    lv_obj_set_size(change_price_btn, 100, 80);
    lv_obj_align(change_price_btn, LV_ALIGN_RIGHT_MID, -100, 0);
    lv_obj_t * change_price_label = lv_label_create(change_price_btn);
    lv_obj_add_style(change_price_label, &style1, 0);
    lv_label_set_text(change_price_label, "修改价格");
    lv_obj_align(change_price_label, LV_ALIGN_CENTER, 0, 0);
    lv_obj_add_event_cb(change_price_btn, change_price, LV_EVENT_SHORT_CLICKED, p);

    //删除商品按钮
    lv_obj_t * delete_btn =  lv_btn_create(tab1);
    lv_obj_set_size(delete_btn, 100, 80);
    lv_obj_align(delete_btn, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
    lv_obj_t * delete_label = lv_label_create(delete_btn);
    lv_obj_add_style(delete_label, &style1, 0);
    lv_label_set_text(delete_label, "删除商品");
    lv_obj_align(delete_label, LV_ALIGN_CENTER, 0, 0);
    lv_obj_add_event_cb(delete_btn, delete_goods, LV_EVENT_SHORT_CLICKED, p);

    lv_obj_t * add_num = lv_btn_create(temp);//加按钮
    lv_obj_t * sub_num = lv_btn_create(temp);//减按钮
    lv_obj_t * btn_back = lv_btn_create(temp);//返回
    lv_obj_t * img_picture  = lv_img_create(temp);//商品图片
    lv_obj_t * label_price  = lv_label_create(temp); //商品价格
    lv_obj_t * label_name   = lv_label_create(temp); //商品名
    lv_obj_t * label_Margin = lv_label_create(temp); //余量

    lv_img_set_src(img_picture, p->jpgpath); // 商品图片
    lv_obj_set_size(img_picture, 100, 128);  // 设置图片大小
    lv_obj_align(img_picture, LV_ALIGN_TOP_MID, 0, 0);

    char buf[128] = {"\0"};
    sprintf(buf, "%d", p->number); // 商品余量
    lv_label_set_text(label_Margin, buf);
    lv_obj_align(label_Margin, LV_ALIGN_CENTER, 0, 70);

    // 显示标签--商品信息
    lv_obj_add_style(label_name, &style1, 0);
    lv_label_set_text(label_name, p->cname); // 商品名
    lv_obj_align(label_name, LV_ALIGN_CENTER, 0, 30);

    sprintf(buf, "¥%.1f", p->price); // 商品价格
    lv_label_set_text(label_price, buf);
    lv_obj_align(label_price, LV_ALIGN_CENTER, 0, 50);

    //加按钮
    lv_obj_set_size(add_num, 50, 50);
    lv_obj_align(add_num, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
    lv_obj_t * add_label = lv_label_create(add_num);//按钮标签
    lv_label_set_text(add_label, LV_SYMBOL_PLUS);
    lv_obj_align(add_label, LV_ALIGN_CENTER, 0, 0);

    //减按钮
    lv_obj_set_size(sub_num, 50, 50);
    lv_obj_align(sub_num, LV_ALIGN_BOTTOM_LEFT, 0, 0);
    lv_obj_t * sub_label = lv_label_create(sub_num);//按钮标签
    lv_label_set_text(sub_label, LV_SYMBOL_MINUS);
    lv_obj_align(sub_label, LV_ALIGN_CENTER, 0, 0);

    //返回按钮
    lv_obj_set_size(btn_back, 60, 50);
    lv_obj_align(btn_back, LV_ALIGN_TOP_LEFT, 0, 0);
    lv_obj_t * back_label = lv_label_create(btn_back);
    lv_obj_align(back_label, LV_ALIGN_CENTER, 0, 0);
    lv_label_set_text(back_label, "back");

    lv_obj_add_event_cb(add_num, manage_add, LV_EVENT_SHORT_CLICKED, p);//加商品
    lv_obj_add_event_cb(sub_num, manage_redu, LV_EVENT_SHORT_CLICKED, p);//减商品
    lv_obj_add_event_cb(btn_back, root_goods, LV_EVENT_SHORT_CLICKED, NULL);//返回

    lv_obj_clear_flag(temp, LV_OBJ_FLAG_SCROLLABLE);

}

//管理员减商品
void manage_redu(lv_event_t *e)
{
    struct link_node *p;
    p = e->user_data;
    if(p->number == 0)
    {
        return;
    }
    p->number--;

    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    lv_obj_clean(lv_scr_act()); // 清理屏幕

    /*选项卡列表*/
    lv_obj_t * tabview;
    tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 0);
    lv_obj_set_size(tabview, 800, 480); // 设置选项卡列表的大小
    lv_obj_set_pos(tabview, 0, 0);
    lv_obj_set_style_bg_color(tabview, lv_color_hex(0xFFFFFF), 0); // 颜色

    //加一个标签选项卡Tab1,不显示
    lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Welcome!");

    lv_obj_t * temp = lv_obj_create(tab1);
    lv_obj_set_size(temp, 350, 350);
    lv_obj_set_style_bg_color(temp, lv_color_hex(0xFFAC2B), 0);
    lv_obj_align(temp, LV_ALIGN_CENTER, 0, 0);

    //修改商品价格按钮
    lv_obj_t * change_price_btn =  lv_btn_create(tab1);
    lv_obj_set_size(change_price_btn, 100, 80);
    lv_obj_align(change_price_btn, LV_ALIGN_RIGHT_MID, -100, 0);
    lv_obj_t * change_price_label = lv_label_create(change_price_btn);
    lv_obj_add_style(change_price_label, &style1, 0);
    lv_label_set_text(change_price_label, "修改价格");
    lv_obj_align(change_price_label, LV_ALIGN_CENTER, 0, 0);
    lv_obj_add_event_cb(change_price_btn, change_price, LV_EVENT_SHORT_CLICKED, p);

    //删除商品按钮
    lv_obj_t * delete_btn =  lv_btn_create(tab1);
    lv_obj_set_size(delete_btn, 100, 80);
    lv_obj_align(delete_btn, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
    lv_obj_t * delete_label = lv_label_create(delete_btn);
    lv_obj_add_style(delete_label, &style1, 0);
    lv_label_set_text(delete_label, "删除商品");
    lv_obj_align(delete_label, LV_ALIGN_CENTER, 0, 0);
    lv_obj_add_event_cb(delete_btn, delete_goods, LV_EVENT_SHORT_CLICKED, p);

    lv_obj_t * add_num = lv_btn_create(temp);//加按钮
    lv_obj_t * sub_num = lv_btn_create(temp);//减按钮
    lv_obj_t * btn_back = lv_btn_create(temp);//返回
    lv_obj_t * img_picture  = lv_img_create(temp);//商品图片
    lv_obj_t * label_price  = lv_label_create(temp); //商品价格
    lv_obj_t * label_name   = lv_label_create(temp); //商品名
    lv_obj_t * label_Margin = lv_label_create(temp); //余量

    lv_img_set_src(img_picture, p->jpgpath); // 商品图片
    lv_obj_set_size(img_picture, 100, 128);  // 设置图片大小
    lv_obj_align(img_picture, LV_ALIGN_TOP_MID, 0, 0);

    char buf[128] = {"\0"};
    sprintf(buf, "%d", p->number); // 商品余量
    lv_label_set_text(label_Margin, buf);
    lv_obj_align(label_Margin, LV_ALIGN_CENTER, 0, 70);

    // 显示标签--商品信息
    lv_obj_add_style(label_name, &style1, 0);
    lv_label_set_text(label_name, p->cname); // 商品名
    lv_obj_align(label_name, LV_ALIGN_CENTER, 0, 30);

    sprintf(buf, "¥%.1f", p->price); // 商品价格
    lv_label_set_text(label_price, buf);
    lv_obj_align(label_price, LV_ALIGN_CENTER, 0, 50);

    //加按钮
    lv_obj_set_size(add_num, 50, 50);
    lv_obj_align(add_num, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
    
    lv_obj_t * add_label = lv_label_create(add_num);
    lv_label_set_text(add_label, LV_SYMBOL_PLUS);
    lv_obj_align(add_label, LV_ALIGN_CENTER, 0, 0);

    //减按钮
    lv_obj_set_size(sub_num, 50, 50);
    lv_obj_align(sub_num, LV_ALIGN_BOTTOM_LEFT, 0, 0);
    
    lv_obj_t * sub_label = lv_label_create(sub_num);
    lv_label_set_text(sub_label, LV_SYMBOL_MINUS);
    lv_obj_align(sub_label, LV_ALIGN_CENTER, 0, 0);

    //返回按钮
    lv_obj_set_size(btn_back, 60, 50);
    lv_obj_align(btn_back, LV_ALIGN_TOP_LEFT, 0, 0);
    lv_obj_t * back_label = lv_label_create(btn_back);
    lv_obj_align(back_label, LV_ALIGN_CENTER, 0, 0);
    lv_label_set_text(back_label, "back");

    lv_obj_add_event_cb(add_num, manage_add, LV_EVENT_SHORT_CLICKED, p);//加商品
    lv_obj_add_event_cb(sub_num, manage_redu, LV_EVENT_SHORT_CLICKED, p);//减商品
    lv_obj_add_event_cb(btn_back, root_goods, LV_EVENT_SHORT_CLICKED, NULL);//减商品

    lv_obj_clear_flag(temp, LV_OBJ_FLAG_SCROLLABLE);

}

//管理员商品加减页面
void manage_goods(lv_event_t *e)
{
    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    struct link_node *p;
    p = e->user_data;

    lv_obj_clean(lv_scr_act()); // 清理屏幕

    /*选项卡列表*/
    lv_obj_t * tabview;
    tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 0);
    lv_obj_set_size(tabview, 800, 480); // 设置选项卡列表的大小
    lv_obj_set_pos(tabview, 0, 0);
    lv_obj_set_style_bg_color(tabview, lv_color_hex(0xFFFFFF), 0); // 颜色

    //加一个标签选项卡Tab1,不显示
    lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Welcome!");
    //lv_obj_set_flex_flow(tab1, LV_FLEX_FLOW_ROW_WRAP); // 布局

    lv_obj_t * temp = lv_obj_create(tab1);
    lv_obj_set_size(temp, 350, 350);
    lv_obj_set_style_bg_color(temp, lv_color_hex(0xFFAC2B), 0);
    lv_obj_align(temp, LV_ALIGN_CENTER, 0, 0);

    //修改商品价格按钮
    lv_obj_t * change_price_btn =  lv_btn_create(tab1);
    lv_obj_set_size(change_price_btn, 100, 80);
    lv_obj_align(change_price_btn, LV_ALIGN_RIGHT_MID, -100, 0);
    lv_obj_t * change_price_label = lv_label_create(change_price_btn);
    lv_obj_add_style(change_price_label, &style1, 0);
    lv_label_set_text(change_price_label, "修改价格");
    lv_obj_align(change_price_label, LV_ALIGN_CENTER, 0, 0);
    lv_obj_add_event_cb(change_price_btn, change_price, LV_EVENT_SHORT_CLICKED, p);

    //删除商品按钮
    lv_obj_t * delete_btn =  lv_btn_create(tab1);
    lv_obj_set_size(delete_btn, 100, 80);
    lv_obj_align(delete_btn, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
    lv_obj_t * delete_label = lv_label_create(delete_btn);
    lv_obj_add_style(delete_label, &style1, 0);
    lv_label_set_text(delete_label, "删除商品");
    lv_obj_align(delete_label, LV_ALIGN_CENTER, 0, 0);
    lv_obj_add_event_cb(delete_btn, delete_goods, LV_EVENT_SHORT_CLICKED, p);

    lv_obj_t * add_num = lv_btn_create(temp);//加按钮
    lv_obj_t * sub_num = lv_btn_create(temp);//减按钮
    lv_obj_t * btn_back = lv_btn_create(temp);//返回
    lv_obj_t * img_picture  = lv_img_create(temp);//商品图片
    lv_obj_t * label_price  = lv_label_create(temp); //商品价格
    lv_obj_t * label_name   = lv_label_create(temp); //商品名
    lv_obj_t * label_Margin = lv_label_create(temp); //余量

    lv_img_set_src(img_picture, p->jpgpath); // 商品图片
    lv_obj_set_size(img_picture, 100, 128);  // 设置图片大小
    lv_obj_align(img_picture, LV_ALIGN_TOP_MID, 0, 0);

    char buf[128] = {"\0"};
    sprintf(buf, "%d", p->number); // 商品余量
    lv_label_set_text(label_Margin, buf);
    lv_obj_align(label_Margin, LV_ALIGN_CENTER, 0, 70);

    // 显示标签--商品信息
    lv_obj_add_style(label_name, &style1, 0);
    lv_label_set_text(label_name, p->cname); // 商品名
    lv_obj_align(label_name, LV_ALIGN_CENTER, 0, 30);

    sprintf(buf, "¥%.1f", p->price); // 商品价格
    lv_label_set_text(label_price, buf);
    lv_obj_align(label_price, LV_ALIGN_CENTER, 0, 50);

    //加按钮
    lv_obj_set_size(add_num, 50, 50);
    lv_obj_align(add_num, LV_ALIGN_BOTTOM_RIGHT, 0, 0);

    lv_obj_t * add_label = lv_label_create(add_num);
    lv_label_set_text(add_label, LV_SYMBOL_PLUS);
    lv_obj_align(add_label, LV_ALIGN_CENTER, 0, 0);

    //减按钮
    lv_obj_set_size(sub_num, 50, 50);
    lv_obj_align(sub_num, LV_ALIGN_BOTTOM_LEFT, 0, 0);
    
    lv_obj_t * sub_label = lv_label_create(sub_num);
    lv_label_set_text(sub_label, LV_SYMBOL_MINUS);
    lv_obj_align(sub_label, LV_ALIGN_CENTER, 0, 0);

    //返回按钮
    lv_obj_set_size(btn_back, 60, 50);
    lv_obj_align(btn_back, LV_ALIGN_TOP_LEFT, 0, 0);
    lv_obj_t * back_label = lv_label_create(btn_back);
    lv_obj_align(back_label, LV_ALIGN_CENTER, 0, 0);
    lv_label_set_text(back_label, "back");

    lv_obj_add_event_cb(add_num, manage_add, LV_EVENT_SHORT_CLICKED, p);//加商品
    lv_obj_add_event_cb(sub_num, manage_redu, LV_EVENT_SHORT_CLICKED, p);//减商品
    lv_obj_add_event_cb(btn_back, root_goods, LV_EVENT_SHORT_CLICKED, NULL);//返回
    
    lv_obj_clear_flag(temp, LV_OBJ_FLAG_SCROLLABLE);
}

//管理员商品管理页面
void root_goods(lv_event_t * e)
{
    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    lv_obj_clean(lv_scr_act()); // 清理屏幕
    
    //设置返回按钮
    lv_obj_t * back_btn = lv_btn_create(lv_scr_act());
    lv_obj_set_size(back_btn, 50, 50);
    lv_obj_set_pos(back_btn, 750, 0);
    lv_obj_t * btn_label = lv_label_create(back_btn);
    lv_label_set_text(btn_label, "back");
    lv_obj_align(btn_label, LV_ALIGN_CENTER, 0, 0);
    lv_obj_add_event_cb(back_btn, lvgl_tab, LV_EVENT_SHORT_CLICKED, NULL);//返会管理页面

    //更新商品信息按钮
    lv_obj_t * update_btn = lv_btn_create(lv_scr_act());
    lv_obj_set_size(update_btn, 50, 50);
    lv_obj_set_pos(update_btn, 750, 215);
    lv_obj_t * update_label = lv_label_create(update_btn);
    lv_label_set_text(update_label, "update");
    lv_obj_align(update_label, LV_ALIGN_CENTER, 0, 0);
    lv_obj_add_event_cb(update_btn, update_goods, LV_EVENT_SHORT_CLICKED, NULL);//商品信息更新到文件

    /*选项卡列表*/
    lv_obj_t * tabview;
    tabview = lv_tabview_create(lv_scr_act(), LV_DIR_LEFT, 0);
    lv_obj_set_size(tabview, 750, 480); // 设置选项卡列表的大小
    lv_obj_set_pos(tabview, 0, 0);
    lv_obj_set_style_bg_color(tabview, lv_color_hex(0xFF7F27), 0); // 颜色

    //选项卡Tab1
    lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Welcome!");
    lv_obj_set_flex_flow(tab1, LV_FLEX_FLOW_ROW_WRAP); //弹性布局,自动帮你布局

    struct link_node *p = head->next;
    while(1)
    {   
        //先进行一次判断,没有商品就退出
        if(p == head)
        {
            printf("manage info complete\n");
            break;
        }
        lv_obj_t * temp = lv_obj_create(tab1);   
        lv_obj_set_size(temp, 160, 260); // 设置商品对象的大小
        lv_obj_t * label_name   = lv_label_create(temp); // 创建标签对象--商品名
        lv_obj_t * label_price  = lv_label_create(temp); // 创建标签对象--商品价格
        lv_obj_t * label_Margin = lv_label_create(temp); // 创建标签对象--商品余量
        lv_obj_t * img_picture  = lv_img_create(temp);   // 创建标签对象--商品照片

        // 显示标签--商品信息
        lv_obj_add_style(label_name, &style1, 0);
        lv_label_set_text(label_name, p->cname); // 商品名
        lv_obj_align(label_name, LV_ALIGN_CENTER, 0, 30);

        char buf[128] = {"\0"};
        sprintf(buf, "%d", p->number); // 商品余量
        lv_label_set_text(label_Margin, buf);
        lv_obj_align(label_Margin, LV_ALIGN_CENTER, 0, 70);

        sprintf(buf, "¥%.1f", p->price); // 商品价格
        lv_label_set_text(label_price, buf);
        lv_obj_align(label_price, LV_ALIGN_CENTER, 0, 50);

        lv_img_set_src(img_picture, p->jpgpath); // 商品图片
        lv_obj_set_size(img_picture, 100, 128);  // 设置图片大小
        lv_obj_set_pos(img_picture, 10, 0);

        lv_obj_add_flag(img_picture, LV_OBJ_FLAG_CLICKABLE); // 使图片可点击
        lv_obj_add_event_cb(img_picture, manage_goods, LV_EVENT_SHORT_CLICKED, p);

        p = p->next;
        if(p == head)
        {
            printf("manage info complete\n");
            break;
        }
    }
    
    lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE);
}

//管理员登录按钮回调函数
static void login_btn_event_cb( lv_event_t * e)
{
    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色


    const char * username = lv_textarea_get_text(usern);//获取输入的电话号码  lv_textarea_get_text(textarea)
    const char * password = lv_textarea_get_text(passw);//获取输入的密码

    if((strcmp(username,LOGIN_USER1)==0 || strcmp(username,LOGIN_USER2)==0) && (strcmp(password,LOGIN_PASSWORD)==0))
    {
        //验证成功
        //显示登录成功
        //弹窗:登录成功,删除所有控件
        lv_obj_t * mbox1 = lv_msgbox_create(lv_scr_act(), "登录", "登录成功", btns, false);
        lv_obj_add_style(mbox1, &style1, 0);
        lv_obj_add_event_cb(mbox1, root_goods, LV_EVENT_VALUE_CHANGED, NULL);
        lv_obj_center(mbox1);

    }
    else
    {
        //验证失败,弹出提示
        //显示登录失败
        lv_obj_t * mbox2 = lv_msgbox_create(lv_scr_act(), "失败", "登录失败\n错误的用户名或密码", btns, false);
        lv_obj_add_style(mbox2, &style1, 0);
        lv_obj_add_event_cb(mbox2, Root_login, LV_EVENT_VALUE_CHANGED, NULL);
        lv_obj_center(mbox2);

    }
}

//管理员界面
static void Root_login(lv_event_t * e)
{
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    //字体样式2
    static lv_ft_info_t info1;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info1.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info1.weight = 24;//字号
    info1.style = FT_FONT_STYLE_NORMAL;//字体风格
    info1.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info1)){ 
        LV_LOG_ERROR("creat.");
    }
    static lv_style_t style2;
    lv_style_init(&style2);
    lv_color_t c1 = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style2, info1.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style2, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style2,c1);//设置该样式文本颜色


    lv_obj_clean(lv_scr_act()); // 清理屏幕
    
    lv_obj_t * img = lv_img_create(lv_scr_act());
    lv_obj_set_size(img, 800, 480); // 设置大小
    lv_obj_set_pos(img, 0, 0);      // 位置
    lv_img_set_src(img, "S:/mdata/project/aa.jpg");//显示图片


    //返回按钮
    lv_obj_t *btn;
    btn = lv_btn_create(lv_scr_act());
    //同时设置部件的大小
    lv_obj_set_size(btn, 150, 70);
    //同时设置部件的起点坐标
    lv_obj_set_pos(btn, 0, 0);
    //设置背景的颜色
    lv_obj_set_style_bg_color(btn, lv_color_hex(0xFF6464),LV_STATE_DEFAULT);    /* 设置部件的样式 */
    lv_obj_t *label1;
    label1 = lv_label_create(btn);
    lv_label_set_text(label1,"back");
    lv_obj_set_align(label1, LV_ALIGN_CENTER);//居中
    lv_obj_add_event_cb(btn, lvgl_tab, LV_EVENT_PRESSED, NULL);
    
    //键盘
    lv_obj_t * kb = lv_keyboard_create(lv_scr_act());
    //用户名文本框
    usern = lv_textarea_create(lv_scr_act());
    lv_obj_align(usern, LV_ALIGN_CENTER, 100, -90);
    lv_obj_add_event_cb(usern, ta_event_cb, LV_EVENT_ALL, kb);
    lv_textarea_set_placeholder_text(usern, "USERNAME");
    lv_textarea_set_one_line(usern, true);//设置单行模式
    lv_obj_set_size(usern, 200, 50);
    //用户名文本框标签
    lv_obj_t * nlabel = lv_label_create(lv_scr_act());//lv_scr_act()
	lv_obj_align(nlabel, LV_ALIGN_CENTER, -60, -80);
    lv_obj_add_style(nlabel, &style2, 0);
	lv_label_set_text(nlabel, "用户名:");
	lv_obj_set_size(nlabel, 90, 50);//设置大小

    //密码文本框
    passw = lv_textarea_create(lv_scr_act());
    lv_obj_align(passw, LV_ALIGN_CENTER, 100, -30);
    lv_obj_add_event_cb(passw, ta_event_cb, LV_EVENT_ALL, kb);
    lv_textarea_set_placeholder_text(passw, "PASSWORD");
    lv_textarea_set_one_line(passw, true);//设置单行模式
    lv_textarea_set_password_mode(passw, true);//启用密码模式,输入内容会显示*或者·
    lv_obj_set_size(passw, 200, 50);
    //密码文本框标签
    lv_obj_t * plabel = lv_label_create(lv_scr_act());//lv_scr_act()
	lv_obj_align(plabel, LV_ALIGN_CENTER, -50, -20);
    lv_obj_add_style(plabel, &style2, 0);
	lv_label_set_text(plabel, "密码:");
	lv_obj_set_size(plabel, 80, 50);//设置大小

    //登录按键
    lv_obj_t *login_btn = lv_btn_create(lv_scr_act());
    lv_obj_align(login_btn, LV_ALIGN_CENTER, 0, 50);
    lv_obj_set_size(login_btn, 120, 50);
    lv_obj_set_style_bg_color(login_btn, lv_color_hex(0xFFFFFF), 0);
    lv_obj_t * label_login = lv_label_create(login_btn);
    lv_obj_add_style(label_login, &style1, 0);
	lv_label_set_text(label_login, "登录");
 	lv_obj_align(label_login, LV_ALIGN_CENTER, 0, 0);

    lv_obj_add_event_cb(login_btn, login_btn_event_cb, LV_EVENT_PRESSED, NULL);//登录回调函数
    lv_obj_set_parent(kb, lv_scr_act());//将键盘置于屏幕的最上层(覆盖按钮)

    lv_keyboard_set_textarea(kb, usern);
}
/*****************/


/**商品购买有关函数**/
//商品增加
void goods_add(lv_event_t * e)
{
    float r;
    char buff[64]={"\0"};
    struct buy_info *bnode;
    
    bnode = e->user_data;
    if(bnode->sum_goods == bnode->node->number)
    {
        return;
    }
    bnode->sum_goods++;

    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    //选择商品界面(标签页)
    lv_obj_t *C_choose = lv_obj_create(lv_scr_act()); 
    lv_obj_set_size(C_choose, 160, 260);//设置大小
    lv_obj_set_pos(C_choose, 640, 50);//设置位置

    lv_obj_t * img_picture = lv_img_create(C_choose);
    lv_img_set_src(img_picture, bnode->node->jpgpath); // 商品图片
    lv_obj_set_size(img_picture, 100, 128);  // 设置图片大小
    lv_obj_align(img_picture, LV_ALIGN_TOP_MID, 0, 0);

    lv_obj_t * label_name  = lv_label_create(C_choose);
    lv_obj_add_style(label_name, &style1, 0);
    lv_label_set_text(label_name, bnode->node->cname); // 商品名
    lv_obj_align(label_name, LV_ALIGN_CENTER, 0, 30);

    //显示购买数量
    lv_obj_t * num1 = lv_label_create(C_choose);
    lv_obj_add_style(num1, &style1, 0);
    sprintf(buff, "数量:%d", bnode->sum_goods);
    lv_label_set_text(num1, buff);
    lv_obj_set_size(num1, 60, 40);                   //设置大小
    lv_obj_align(num1, LV_ALIGN_BOTTOM_LEFT, -20, 35);  //设置位置

    //购买数量的总价格
    r = bnode->node->price * bnode->sum_goods;
    memset(buff, 0, sizeof(buff));
    lv_obj_t * num2 = lv_label_create(C_choose);
    sprintf(buff, "¥%.1f", r);
    lv_label_set_text(num2, buff);
    lv_obj_set_size(num2, 50, 40);
    lv_obj_align(num2, LV_ALIGN_BOTTOM_RIGHT, 5, 35);

    //添加添加按钮
    lv_obj_t *add = lv_obj_create(lv_scr_act());
    lv_obj_set_size(add, 50, 50);
    lv_obj_set_pos(add, 750, 310);
    lv_obj_t * add_picture = lv_img_create(lv_scr_act());//添加图片
    lv_obj_set_pos(add_picture, 750, 310);
    lv_img_set_src(add_picture, "S:/mdata/project/add.jpg");

    //添加减少按钮
    lv_obj_t *down = lv_obj_create(lv_scr_act());
    lv_obj_set_size(down, 50, 50);
    lv_obj_set_pos(down, 640, 310);
    lv_obj_t * down_picture = lv_img_create(lv_scr_act());//添加图片
    lv_obj_set_pos(down_picture, 640, 310);
    lv_img_set_src(down_picture, "S:/mdata/project/down.jpg");

    //添加确认按钮
    lv_obj_t * btn1 = lv_obj_create(lv_scr_act());
    lv_obj_set_size(btn1, 85, 65);
    lv_obj_align(btn1, LV_ALIGN_BOTTOM_LEFT, 715, 0);
    lv_obj_set_style_bg_color(btn1, lv_color_hex(0x4BFF6C), 0);
    lv_obj_t * label_en = lv_label_create(btn1);
    lv_obj_add_style(label_en, &style1, 0);
    lv_label_set_text(label_en, "确认");
    lv_obj_center(label_en);

    lv_obj_add_event_cb(add, goods_add, LV_EVENT_SHORT_CLICKED, bnode);//商品增加
    lv_obj_add_event_cb(down, goods_redu, LV_EVENT_SHORT_CLICKED, bnode);//商品减少
    lv_obj_add_event_cb(btn1, decide_buy, LV_EVENT_SHORT_CLICKED, bnode);//确认购买

    lv_obj_clear_flag(C_choose, LV_OBJ_FLAG_SCROLLABLE);
}

//商品减少
void goods_redu(lv_event_t * e)
{
    float r;
    char buff[64]={"\0"};
    struct buy_info *bnode;
    bnode = e->user_data;
    if(bnode->sum_goods == 1)
    {
        return;
    }
    bnode->sum_goods--;

    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    //选择商品界面(标签页)
    lv_obj_t *C_choose = lv_obj_create(lv_scr_act()); 
    lv_obj_set_size(C_choose, 160, 260);//设置大小
    lv_obj_set_pos(C_choose, 640, 50);//设置位置

    lv_obj_t * img_picture = lv_img_create(C_choose);
    lv_img_set_src(img_picture, bnode->node->jpgpath); // 商品图片
    lv_obj_set_size(img_picture, 100, 128);  // 设置图片大小
    lv_obj_align(img_picture, LV_ALIGN_TOP_MID, 0, 0);

    lv_obj_t * label_name  = lv_label_create(C_choose);
    lv_obj_add_style(label_name, &style1, 0);
    lv_label_set_text(label_name, bnode->node->cname); // 商品名
    lv_obj_align(label_name, LV_ALIGN_CENTER, 0, 30);

    //显示购买数量
    lv_obj_t * num1 = lv_label_create(C_choose);
    lv_obj_add_style(num1, &style1, 0);
    sprintf(buff, "数量:%d", bnode->sum_goods);
    lv_label_set_text(num1, buff);
    lv_obj_set_size(num1, 60, 40);                   //设置大小
    lv_obj_align(num1, LV_ALIGN_BOTTOM_LEFT, -20, 35);  //设置位置

    //购买数量的总价格
    r = bnode->node->price * bnode->sum_goods;
    memset(buff, 0, sizeof(buff));
    lv_obj_t * num2 = lv_label_create(C_choose);
    sprintf(buff, "¥%.1f", r);
    lv_label_set_text(num2, buff);
    lv_obj_set_size(num2, 50, 40);
    lv_obj_align(num2, LV_ALIGN_BOTTOM_RIGHT, 5, 35);

    //添加添加按钮
    lv_obj_t *add = lv_obj_create(lv_scr_act());
    lv_obj_set_size(add, 50, 50);
    lv_obj_set_pos(add, 750, 310);
    lv_obj_t * add_picture = lv_img_create(lv_scr_act());//添加图片
    lv_obj_set_pos(add_picture, 750, 310);
    lv_img_set_src(add_picture, "S:/mdata/project/add.jpg");

    //添加减少按钮
    lv_obj_t *down = lv_obj_create(lv_scr_act());
    lv_obj_set_size(down, 50, 50);
    lv_obj_set_pos(down, 640, 310);
    lv_obj_t * down_picture = lv_img_create(lv_scr_act());//添加图片
    lv_obj_set_pos(down_picture, 640, 310);
    lv_img_set_src(down_picture, "S:/mdata/project/down.jpg");

    //添加确认按钮
    lv_obj_t * btn1 = lv_obj_create(lv_scr_act());
    lv_obj_set_size(btn1, 85, 65);
    lv_obj_align(btn1, LV_ALIGN_BOTTOM_LEFT, 715, 0);
    lv_obj_set_style_bg_color(btn1, lv_color_hex(0x4BFF6C), 0);
    lv_obj_t * label_en = lv_label_create(btn1);
    lv_obj_add_style(label_en, &style1, 0);
    lv_label_set_text(label_en, "确认");
    lv_obj_center(label_en);

    lv_obj_add_event_cb(add, goods_add, LV_EVENT_SHORT_CLICKED, bnode);//商品增加
    lv_obj_add_event_cb(down, goods_redu, LV_EVENT_SHORT_CLICKED, bnode);//商品增加
    lv_obj_add_event_cb(btn1, decide_buy, LV_EVENT_SHORT_CLICKED, bnode);//确认购买

    lv_obj_clear_flag(C_choose, LV_OBJ_FLAG_SCROLLABLE);
}

//确认购买
void decide_buy(lv_event_t * e)
{
    //创建个字体
    static lv_ft_info_t info2;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info2.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info2.weight = 36;//字号
    info2.style = FT_FONT_STYLE_NORMAL;//字体风格
    info2.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info2)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style2;
    lv_style_init(&style2);
    lv_color_t c = lv_color_hex(0xFF000000);
    lv_style_set_text_font(&style2, info2.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style2, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style2,c);//设置该样式文本颜色

    struct buy_info *bnode;
    bnode = e->user_data;

    //选项卡
    lv_obj_t * tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 0);
    lv_obj_set_size(tabview, 800, 480);
    lv_obj_set_pos(tabview, 0, 0);
    lv_obj_set_style_bg_color(tabview, lv_color_hex(0xFFF0D3), 0);
    lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Welcome!");
    
    //文本
    lv_obj_t * label = lv_label_create(tab1);
    lv_obj_set_size(label, 400, 80);
    lv_obj_add_style(label, &style2, 0);
    lv_label_set_text(label, "请选择付款方式");
    lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 0);
    
    //微信支付
    lv_obj_t *wechat = lv_img_create(tab1);
    lv_img_set_src(wechat, "S:/mdata/project/pay/wechat.jpg"); 
    lv_obj_set_size(wechat, 250, 340);  // 设置图片大小
    lv_obj_align(wechat, LV_ALIGN_CENTER, -130, 10);
    lv_obj_add_flag(wechat, LV_OBJ_FLAG_CLICKABLE); // 使图片可点击
    //lv_obj_set_pos(wechat, 10, 0);

    //支付宝支付
    lv_obj_t *alipay = lv_img_create(tab1);
    lv_img_set_src(alipay, "S:/mdata/project/pay/alipay.jpg"); 
    lv_obj_set_size(alipay, 250, 340);  // 设置图片大小
    lv_obj_align(alipay, LV_ALIGN_CENTER, 130, 10);
    lv_obj_add_flag(alipay, LV_OBJ_FLAG_CLICKABLE); // 使图片可点击

    //返回
    lv_obj_t * btn_back = lv_btn_create(lv_scr_act());
    lv_obj_set_size(btn_back, 60, 50);
    lv_obj_align(btn_back, LV_ALIGN_BOTTOM_LEFT, 0, 0);
    lv_obj_t * back_label = lv_label_create(btn_back);
    lv_obj_align(back_label, LV_ALIGN_CENTER, 0, 0);
    lv_label_set_text(back_label, "back");

    lv_obj_add_event_cb(btn_back, lvgl_tab, LV_EVENT_PRESSED, NULL);//不买回到选择商品页
    lv_obj_add_event_cb(wechat, wechat_success, LV_EVENT_SHORT_CLICKED, bnode);//微信支付
    lv_obj_add_event_cb(alipay, alipay_success, LV_EVENT_SHORT_CLICKED, bnode);//支付宝支付

    lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE);
}

//微信支付成功
void wechat_success(lv_event_t * e)
{
    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色


    float money;
    char send_buff[256] = {0};
    struct buy_info *bnode;
    bnode = e->user_data;
    bnode->node->number = bnode->node->number - bnode->sum_goods;
    money = bnode->node->price * bnode->sum_goods;
    sprintf(send_buff, "%d %s %d %.1f %s", 1, bnode->node->cname, bnode->sum_goods, money, wepay);
    send(sockfd, send_buff, strlen(send_buff), 0);

    
    lv_obj_t * mbox1 = lv_msgbox_create(lv_scr_act(), "支付", "支付成功", btns, false);
    lv_obj_add_style(mbox1, &style1, 0);
    lv_obj_add_event_cb(mbox1, lvgl_tab, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_center(mbox1);
}

//支付宝支付成功
void alipay_success(lv_event_t * e)
{
    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    float money;
    char send_buff[256] = {0};
    struct buy_info *bnode;
    bnode = e->user_data;
    bnode->node->number = bnode->node->number - bnode->sum_goods;
    money = bnode->node->price * bnode->sum_goods;
    sprintf(send_buff, "%d %s %d %.1f %s", 1, bnode->node->cname, bnode->sum_goods, money, apay);
    send(sockfd, send_buff, strlen(send_buff), 0);

    lv_obj_t * mbox1 = lv_msgbox_create(lv_scr_act(), "支付", "支付成功", btns, false);
    lv_obj_add_style(mbox1, &style1, 0);
    lv_obj_add_event_cb(mbox1, lvgl_tab, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_center(mbox1);
}

//商品选择
void goods_Choose(lv_event_t * e)
{
    char buff[64]={"\0"};
    struct buy_info *bnode;
    bnode = malloc(sizeof(struct buy_info));//申请大结构体空间
    bnode->node = e->user_data;
    bnode->sum_goods = 1;

    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色

    //选择商品界面(标签页)
    lv_obj_t *C_choose = lv_obj_create(lv_scr_act()); 
    lv_obj_set_size(C_choose, 160, 260);//设置大小
    lv_obj_set_pos(C_choose, 640, 50);//设置位置

    lv_obj_t * img_picture = lv_img_create(C_choose);
    lv_img_set_src(img_picture, bnode->node->jpgpath); // 商品图片
    lv_obj_set_size(img_picture, 100, 128);  // 设置图片大小
    lv_obj_align(img_picture, LV_ALIGN_TOP_MID, 0, 0);

    lv_obj_t * label_name  = lv_label_create(C_choose);
    lv_obj_add_style(label_name, &style1, 0);
    lv_label_set_text(label_name, bnode->node->cname); // 商品名
    lv_obj_align(label_name, LV_ALIGN_CENTER, 0, 30);

    //显示购买数量
    lv_obj_t * num1 = lv_label_create(C_choose);
    lv_obj_add_style(num1, &style1, 0);
    sprintf(buff, "数量:%d", bnode->sum_goods);
    lv_label_set_text(num1, buff);
    lv_obj_set_size(num1, 60, 40);                   //设置大小
    lv_obj_align(num1, LV_ALIGN_BOTTOM_LEFT, -20, 35);  //设置位置

    //购买数量的总价格
    memset(buff, 0, sizeof(buff));
    lv_obj_t * num2 = lv_label_create(C_choose);
    sprintf(buff, "¥%.1f", bnode->node->price);
    lv_label_set_text(num2, buff);
    lv_obj_set_size(num2, 50, 40);
    lv_obj_align(num2, LV_ALIGN_BOTTOM_RIGHT, 5, 35);

    //添加添加按钮
    lv_obj_t *add = lv_obj_create(lv_scr_act());
    lv_obj_set_size(add, 50, 50);
    lv_obj_set_pos(add, 750, 310);
    lv_obj_t * add_picture = lv_img_create(lv_scr_act());
    lv_obj_set_pos(add_picture, 750, 310);
    lv_img_set_src(add_picture, "S:/mdata/project/add.jpg");

    //添加减少按钮
    lv_obj_t *down = lv_obj_create(lv_scr_act());
    lv_obj_set_size(down, 50, 50);
    lv_obj_set_pos(down, 640, 310);
    lv_obj_t * down_picture = lv_img_create(lv_scr_act());
    lv_obj_set_pos(down_picture, 640, 310);
    lv_img_set_src(down_picture, "S:/mdata/project/down.jpg");

    //添加确认按钮
    lv_obj_t * btn1 = lv_obj_create(lv_scr_act());
    lv_obj_set_size(btn1, 85, 65);
    lv_obj_align(btn1, LV_ALIGN_BOTTOM_LEFT, 715, 0);
    lv_obj_set_style_bg_color(btn1, lv_color_hex(0x4BFF6C), 0);
    lv_obj_t * label_en = lv_label_create(btn1);
    lv_obj_add_style(label_en, &style1, 0);
    lv_label_set_text(label_en, "确认");
    lv_obj_center(label_en);

    lv_obj_add_event_cb(add, goods_add, LV_EVENT_SHORT_CLICKED, bnode);//商品增加
    lv_obj_add_event_cb(btn1, decide_buy, LV_EVENT_SHORT_CLICKED, bnode);//确认购买

    lv_obj_clear_flag(C_choose, LV_OBJ_FLAG_SCROLLABLE);
    //lv_style_set_pattern_image(&style, LV_STATE_DEFAULT, LV_SYMBOL_BLUETOOTH);
}

//商品选择
void goods_search_Choose(struct link_node *node)
{
    char buff[64]={"\0"};
    struct buy_info *bnode;
    bnode = malloc(sizeof(struct buy_info));//申请大结构体空间
    bnode->node = node;
    bnode->sum_goods = 1;

    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色


    //选择商品界面(标签页)
    lv_obj_t *C_choose = lv_obj_create(lv_scr_act()); 
    lv_obj_set_size(C_choose, 160, 260);//设置大小
    lv_obj_set_pos(C_choose, 640, 50);//设置位置

    lv_obj_t * img_picture = lv_img_create(C_choose);
    lv_img_set_src(img_picture, bnode->node->jpgpath); // 商品图片
    lv_obj_set_size(img_picture, 100, 128);  // 设置图片大小
    lv_obj_align(img_picture, LV_ALIGN_TOP_MID, 0, 0);

    lv_obj_t * label_name  = lv_label_create(C_choose);
    lv_obj_add_style(label_name, &style1, 0);
    lv_label_set_text(label_name, bnode->node->cname); // 商品名
    lv_obj_align(label_name, LV_ALIGN_CENTER, 0, 30);

    //显示购买数量
    lv_obj_t * num1 = lv_label_create(C_choose);
    lv_obj_add_style(num1, &style1, 0);
    sprintf(buff, "数量:%d", bnode->sum_goods);
    lv_label_set_text(num1, buff);
    lv_obj_set_size(num1, 60, 40);                   //设置大小
    lv_obj_align(num1, LV_ALIGN_BOTTOM_LEFT, -20, 35);  //设置位置

    //购买数量的总价格
    memset(buff, 0, sizeof(buff));
    lv_obj_t * num2 = lv_label_create(C_choose);
    sprintf(buff, "¥%.1f", bnode->node->price);
    lv_label_set_text(num2, buff);
    lv_obj_set_size(num2, 50, 40);
    lv_obj_align(num2, LV_ALIGN_BOTTOM_RIGHT, 5, 35);

    //添加添加按钮
    lv_obj_t *add = lv_obj_create(lv_scr_act());
    lv_obj_set_size(add, 50, 50);
    lv_obj_set_pos(add, 750, 310);
    lv_obj_t * add_picture = lv_img_create(lv_scr_act());
    lv_obj_set_pos(add_picture, 750, 310);
    lv_img_set_src(add_picture, "S:/mdata/project/add.jpg");

    //添加减少按钮
    lv_obj_t *down = lv_obj_create(lv_scr_act());
    lv_obj_set_size(down, 50, 50);
    lv_obj_set_pos(down, 640, 310);
    lv_obj_t * down_picture = lv_img_create(lv_scr_act());
    lv_obj_set_pos(down_picture, 640, 310);
    lv_img_set_src(down_picture, "S:/mdata/project/down.jpg");

    //添加确认按钮
    lv_obj_t * btn1 = lv_obj_create(lv_scr_act());
    lv_obj_set_size(btn1, 85, 65);
    lv_obj_align(btn1, LV_ALIGN_BOTTOM_LEFT, 715, 0);
    lv_obj_set_style_bg_color(btn1, lv_color_hex(0x4BFF6C), 0);
    lv_obj_t * label_en = lv_label_create(btn1);
    lv_obj_add_style(label_en, &style1, 0);
    lv_label_set_text(label_en, "确认");
    lv_obj_center(label_en);

    lv_obj_add_event_cb(add, goods_add, LV_EVENT_SHORT_CLICKED, bnode);//商品增加
    lv_obj_add_event_cb(btn1, decide_buy, LV_EVENT_SHORT_CLICKED, bnode);//确认购买

    lv_obj_clear_flag(C_choose, LV_OBJ_FLAG_SCROLLABLE);
    //lv_style_set_pattern_image(&style, LV_STATE_DEFAULT, LV_SYMBOL_BLUETOOTH);
}

//搜索框加键盘
void search_box(void)
{
    //文本框
    search = lv_textarea_create(lv_scr_act());
    lv_obj_add_event_cb(search, chack_search, LV_EVENT_SHORT_CLICKED, NULL);
    lv_textarea_set_placeholder_text(search, "SEARCH");
    lv_textarea_set_one_line(search, true);//设置单行模式
    lv_obj_set_size(search, 110, 50);
    lv_obj_set_pos(search, 640, 0);

    //搜索按钮
    lv_obj_t * search_btn = lv_btn_create(lv_scr_act());
    lv_obj_set_size(search_btn, 50, 50);
    lv_obj_set_pos(search_btn, 750, 0);
    lv_obj_t * search_label = lv_label_create(search_btn);
    lv_label_set_text(search_label, LV_SYMBOL_FILE);
    lv_obj_align(search_label, LV_ALIGN_CENTER, 0, 0);

    lv_obj_add_event_cb(search_btn, search_goods, LV_EVENT_PRESSED, NULL);
}

//点击搜索框
void chack_search(lv_event_t * e)
{
    lv_obj_t * kb = lv_keyboard_create(lv_scr_act());//键盘
    lv_obj_set_parent(kb, lv_scr_act());//将键盘置于屏幕的最上层(覆盖按钮)
    lv_obj_set_size(kb, 640, 200);
    lv_obj_align(kb, LV_ALIGN_BOTTOM_LEFT, 0, 0);

    //文本框
    search = lv_textarea_create(lv_scr_act());
    lv_obj_add_event_cb(search, ta_event_cb, LV_EVENT_ALL, kb);
    lv_textarea_set_placeholder_text(search, "SEARCH");
    lv_textarea_set_one_line(search, true);//设置单行模式
    lv_obj_set_size(search, 110, 50);
    lv_obj_set_pos(search, 640, 0);

}

//搜索
void search_goods(lv_event_t * e)
{
    const char * search_area = lv_textarea_get_text(search);//获取输入商品信息
    struct link_node *p;
    p = head->next;

    for(p; p->next != head; p=p->next)
    {
        if(strcmp(search_area, p->name)==0)
        {
            printf("find\n");
            goods_search_Choose(p);
            break;
        }
    }
}   

//选项卡
void lvgl_tab(lv_event_t * e)
{
    //字体格式1
    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 16;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色
 

    /*字体格式2*/
    //创建第二个个字体
    static lv_ft_info_t info2;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info2.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info2.weight = 26;//字号
    info2.style = FT_FONT_STYLE_NORMAL;//字体风格
    info2.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info2)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style2;
    lv_style_init(&style2);
    lv_style_set_text_font(&style2, info2.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style2, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style2,c);//设置该样式文本颜色


    lv_obj_clean(lv_scr_act()); // 清理屏幕

    //选择商品界面
    lv_obj_t *C_choose = lv_obj_create(lv_scr_act()); 
    lv_obj_set_size(C_choose, 160, 260);
    lv_obj_set_pos(C_choose, 640, 50);

    //初始提示语
    lv_obj_t * label_wel = lv_label_create(C_choose); 
    lv_obj_align(label_wel, LV_ALIGN_CENTER, 0, 20);
    lv_obj_add_style(label_wel, &style2, 0);
    lv_label_set_text(label_wel, "欢迎!");
    lv_obj_set_width(label_wel, 100);
    lv_obj_set_height(label_wel, 80);
    
    // 确定按钮
    lv_obj_t * btn1 = lv_obj_create(lv_scr_act());
    lv_obj_set_size(btn1, 85, 65);
    lv_obj_align(btn1, LV_ALIGN_BOTTOM_LEFT, 715, 0);
    lv_obj_t * label_en = lv_label_create(btn1);
    lv_obj_add_style(label_en, &style1, 0);
    lv_label_set_text(label_en, "确认");
    lv_obj_center(label_en);

    /*选项卡列表*/
    lv_obj_t * tabview;
    tabview = lv_tabview_create(lv_scr_act(), LV_DIR_LEFT, 0);//为0表示选项卡不显示
    lv_obj_set_size(tabview, 570, 480); // 设置选项卡列表的大小
    lv_obj_set_pos(tabview, 70, 0);
    lv_obj_set_style_bg_color(tabview, lv_palette_lighten(LV_PALETTE_LIGHT_BLUE, 2), 0); // 颜色
    
    lv_obj_t * tab_btns = lv_tabview_get_tab_btns(tabview);
    lv_obj_set_style_bg_color(tab_btns, lv_palette_darken(LV_PALETTE_BLUE, 3), 0);
    lv_obj_set_style_text_color(tab_btns, lv_palette_lighten(LV_PALETTE_BLUE, 6), 0);
    lv_obj_set_style_border_side(tab_btns, LV_BORDER_SIDE_RIGHT, LV_PART_ITEMS | LV_STATE_CHECKED);

    //管理员功能
    lv_obj_t * btn2 = lv_btn_create(lv_scr_act());
    lv_obj_set_size(btn2, 70, 480);
    lv_obj_set_pos(btn2, 0, 0);
    lv_obj_t * label_en2 = lv_label_create(btn2);
    lv_label_set_text(label_en2, "Root");
    lv_obj_center(label_en2);
    lv_obj_add_event_cb(btn2, Root_login, LV_EVENT_LONG_PRESSED, NULL); // 点击广告调出主界面

    //选项卡Tab1
    lv_obj_t * tab1 = lv_tabview_add_tab(tabview, "Welcome!");
    lv_obj_set_flex_flow(tab1, LV_FLEX_FLOW_ROW_WRAP); // 布局

    struct link_node *p = head->next;
    char send_buff[256]={0};
    while(1)
    {
        if(p == head)
        {
            printf("info complete\n");
            break;
        }
        lv_obj_t * temp = lv_obj_create(tab1);   
        lv_obj_set_size(temp, 160, 260); // 设置商品对象的大小
        lv_obj_t * label_name   = lv_label_create(temp); // 创建标签对象--商品名
        lv_obj_t * label_price  = lv_label_create(temp); // 创建标签对象--商品价格
        lv_obj_t * label_Margin = lv_label_create(temp); // 创建标签对象--商品余量
        lv_obj_t * img_picture  = lv_img_create(temp);   // 创建标签对象--商品照片

        if(p->number > 0) // 商品余量大于0,可以购买
        {
            lv_obj_t * C_add = lv_obj_create(temp); // 购买
            lv_obj_align(C_add, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
            lv_obj_set_size(C_add, 35, 35);
            lv_obj_add_event_cb(C_add, goods_Choose, LV_EVENT_SHORT_CLICKED, p); // 调用选择商品函数
            lv_obj_t * img_picture1 = lv_img_create(temp);                  // 图片
            lv_obj_align(img_picture1, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
            lv_img_set_src(img_picture1, "S:/mdata/project/buy.jpg");
        }
        if(p->number == 0) // 少于0则不能购买,显示为NULL
        {
            sprintf(send_buff, "%d %s", 2, p->cname);
            send(sockfd, send_buff, strlen(send_buff), 0);
            lv_obj_t * label_null = lv_label_create(temp);
            lv_label_set_text(label_null, "NULL!");
            lv_obj_align(label_null, LV_ALIGN_BOTTOM_RIGHT, 0, 0);
            memset(send_buff, 0, sizeof(send_buff));
        }

        // 显示标签--商品信息
        lv_obj_add_style(label_name, &style1, 0);
        lv_label_set_text(label_name, p->cname); // 商品名
        lv_obj_align(label_name, LV_ALIGN_CENTER, 0, 30);

        char buf[128] = {"\0"};
        sprintf(buf, "¥%.1f", p->price); //转为字符串
        lv_label_set_text(label_price, buf);// 商品价格
        lv_obj_align(label_price, LV_ALIGN_BOTTOM_LEFT, 20, 0);

        sprintf(buf, "%d", p->number); // 商品余量
        lv_label_set_text(label_Margin, buf);
        lv_obj_align(label_Margin, LV_ALIGN_CENTER, 0, 50);

        lv_img_set_src(img_picture, p->jpgpath); // 商品图片
        lv_obj_set_size(img_picture, 100, 128);  // 设置图片大小
        lv_obj_set_pos(img_picture, 10, 0);

        p = p->next;
        if(p == head)
        {
            printf("info complete\n");
            break;
        }
    }
    search_box();//搜索框加键盘
    lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE);
}

//开屏广告
void Advertisement(void)
{
    /*创建一个字体*/
    static lv_ft_info_t info;//定义一个记录freetype字体信息的结构体
    /*记录字体文件路径(开发板) 字号大小-单位借用  字体风格*/
    info.name = "/font/simkai.ttf";//字体文件名---华文楷体--文件已经放在开发板中
    info.weight = 36;//字号
    info.style = FT_FONT_STYLE_NORMAL;//字体风格
    info.mem = NULL;//指向字体数据的指针 一般要显示字体时,就会从上面字体文件中获取对应数据 freetype转换为位图数据 ,而mem指针指向这块数据
    //初始化
    if(!lv_ft_font_init(&info)){ 
        LV_LOG_ERROR("creat.");
    }
    /*将上面字体添加到下面的lvgl样式对象中*/
    static lv_style_t style1;
    lv_style_init(&style1);
    lv_color_t c = lv_color_hex(0xFF000000);//定义颜色值  黑色
    lv_style_set_text_font(&style1, info.font);//设置该样式制定的字体--上面的
    lv_style_set_text_align(&style1, LV_TEXT_ALIGN_CENTER);//设置该样式的文本对齐
    lv_style_set_text_color(&style1,c);//设置该样式文本颜色


    lv_obj_clean(lv_scr_act()); // 清理屏幕
    lv_obj_t * img_advertisement = lv_img_create(lv_scr_act());
    lv_obj_set_size(img_advertisement, 800, 480); // 设置大小
    lv_obj_set_pos(img_advertisement, 0, 0);      // 位置
    lv_img_set_src(img_advertisement, "S:/mdata/project/gg.jpg");
    lv_obj_add_flag(img_advertisement, LV_OBJ_FLAG_CLICKABLE); // 使图片可点击

    // 滚动文字
    lv_obj_t * label1 = lv_label_create(lv_scr_act());
    lv_obj_add_style(label1, &style1, 0);
    lv_label_set_long_mode(label1, LV_LABEL_LONG_SCROLL_CIRCULAR); // 滚动文字
    lv_obj_set_width(label1, 400);
    lv_obj_set_height(label1, 80);
 
    lv_label_set_text(label1, "长按屏幕开始购买!长按屏幕开始购买!长按屏幕开始购买!"); // 文本

    lv_obj_set_style_text_color(label1, lv_color_hex(0xFFFF00), 0); // 字体颜色
    lv_obj_align(label1, LV_ALIGN_BOTTOM_MID, 0, 0); //位置;参考对象,对齐方式,x轴偏移量,y轴偏移量
    lv_obj_add_event_cb(img_advertisement, lvgl_tab, LV_EVENT_LONG_PRESSED, NULL); // 点击广告调出主界

}


//客户端接受数据
void *recv_data(void *arg)
{
    int newcentfd = *((int*)arg);
    char recv_buff[1024]={0};
    int ret;
    struct link_node *new_node;

    while(1)
    {
        //接收新商品信息
        ret = recv(newcentfd, recv_buff, sizeof(recv_buff), 0);
        if(ret == 0)
        {
            perror("recv id error!");
            return NULL;
        }

        new_node = request_link_node();

        printf("recv:%s\n", recv_buff);

        //按格式拆分到节点中
        sscanf(recv_buff, "%s %s %s %f %d\n", new_node->jpgpath, new_node->cname, new_node->name, &new_node->price, &new_node->number);
        
        
        insert_node_to_list_tail(head, new_node);
        
        FILE *fp;
        fp = fopen("goods.txt", "a");
        if(fp == NULL)
        {
            perror("open fail");
            return NULL;
        }
        fprintf(fp, "%s %s %s %f %d\n", new_node->jpgpath, new_node->cname, new_node->name, new_node->price, new_node->number);
        fclose(fp);
    }   
}

//主函数
int main(void)
{
    lv_init(); //LVGL程序的初始化

    head = request_link_node();//头节点初始化
    
    goods_info();

    //第一个部分:对液晶屏进行初始化和注册
    fbdev_init(); //液晶屏的初始化,就是用open打开液晶屏的驱动,然后ioctl获取了液晶屏的参数信息,mmap映射得到了首地址

    /*A small buffer for LittlevGL to draw the screen's content*/
    static lv_color_t buf[DISP_BUF_SIZE];  //定义数组存放要显示的内容 屏幕缓冲区

    static lv_disp_draw_buf_t disp_buf;
    lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);  //把你刚才定义的那个buf注册到disp_buf里面

    static lv_disp_drv_t disp_drv;  //是个结构体
    lv_disp_drv_init(&disp_drv);  //初始化液晶屏的驱动,注册相关的信息
    disp_drv.draw_buf   = &disp_buf;     //把液晶屏的缓冲区保存
    disp_drv.flush_cb   = fbdev_flush;   //函数指针,fbdev_flush函数是LVGL画点函数
    disp_drv.hor_res    = 800;  //分辨率
    disp_drv.ver_res    = 480;
    lv_disp_drv_register(&disp_drv); //把液晶屏注册到LVGL中

    //第二个部分:对触摸屏进行初始化和注册
    evdev_init();  //open打开触摸屏
    static lv_indev_drv_t indev_drv_1; //结构体变量
    lv_indev_drv_init(&indev_drv_1);   //初始化刚才的结构体变量
    indev_drv_1.type = LV_INDEV_TYPE_POINTER; //触摸类型

    indev_drv_1.read_cb = evdev_read;  //函数指针,读取保存触摸屏坐标
    lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1); //把触摸屏注册到LVGL


    //主代码
    int ret;
    //建立套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd == -1)
    {
        printf("socket failure\n");
        return -1;
    }

    clientAddr.sin_family = AF_INET; //协议 -- IPV4
    clientAddr.sin_port =   htons (40000)  ;  // 绑定端口号
    clientAddr.sin_addr.s_addr =  inet_addr("192.168.7.211");//绑定开发板的IP地址
    /*ret = bind(sockfd, (struct sockaddr *)&clientAddr, sizeof(struct sockaddr_in));
    if(ret == -1)
    {
        printf("bind fail\n");
        return -1;
    }*/

    //绑定服务端的IP 宏定义
    serverAddr.sin_family = AF_INET; //协议 -- IPV4
    serverAddr.sin_port =   htons (50000)  ;  // 绑定端口号
    serverAddr.sin_addr.s_addr =  inet_addr("192.168.7.212");//绑定Ubuntu的IP地址

    //不连上不往下执行程序
    while(1)
    {
        //连接服务端
        ret = connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr_in));
        if(ret != -1)
        {
            printf("connect success\n");
            break;;
        }
    }

    //设置线程
    pthread_t thread;
    //设置线程分离属性
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    //创建线程,接收数据
    pthread_create(&thread, &attr, recv_data, &sockfd);

    Advertisement();//开屏广告

    
    
    unsigned int time_count = 0;//计算屏幕空闲时间
    while(1) {
        lv_timer_handler(); //采用轮询的方式,进行各种事件的响应
        usleep(5000); //5ms

        /*屏幕无操作返回广告页面*/
        //printf("lv_timer_get_idle() = %d\n", lv_timer_get_idle());
        //屏幕空闲等于100时,开始计数
        if(lv_timer_get_idle() >= 100)
        {
            time_count++;
            //printf("time_count = %d\n", time_count);
        }
 
        //不等于100时计数清零
        else
        {
            time_count = 0;
        }
        if(time_count >= 3000)//计数达到3000,大约20秒
        {
            Advertisement();//跳转广告页面
        }
    }

    return 0;
}

/*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
uint32_t custom_tick_get(void)
{
    static uint64_t start_ms = 0;
    if(start_ms == 0) {
        struct timeval tv_start;
        gettimeofday(&tv_start, NULL);
        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
    }

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    uint64_t now_ms;
    now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    uint32_t time_ms = now_ms - start_ms;
    return time_ms;
}

注意事项:

运行商品信息生成代码,将商品信息文件发送到开发板,将所用图片放进开发板中,自己将主函数中的路径和名字进行修改,改成自己的。

代码中有用到中文字体,详细看这里有道云笔记 (youdao.com)

支付图片需要自己制作两张,不提供。(图片大小可根据部件代码参数进行制作)

因为本人是个大懒b,代码没有一点优化,大家将就着看吧。

代码文件和工程所用到的文件都在里(大概)

【免费】基于LVGL的自动贩卖机系统-GEC6818开发板资源-CSDN文库

  • 15
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值