一、参考
1、LVGL移植到ARM开发板(GEC6818开发板)_6818 lvgl-CSDN博客https://blog.csdn.net/wwwqqq2014/article/details/136690316?spm=1001.2014.3001.5502 2、基于GEC6818开发板实现自动贩卖机(C语言 + lvgl库 + 系统编程 + 网络编程 + sqlite3数据库)_使用lvgl图形库开发一款基于linux操作系统的自动售卖机软件-CSDN博客
https://blog.csdn.net/m0_74143852/article/details/133494058 3、LVGL不同版本的百问网
-
LVGL V7.11: 百问网LVGL中文教程手册文档 — 百问网LVGL中文教程手册文档 1.0 文档
-
LVGL V8.1: 欢迎阅读百问网LVGL中文开发手册! — 百问网LVGL中文教程文档 文档
-
LVGL V8.2: 欢迎阅读百问网LVGL中文开发手册! — 百问网LVGL中文教程文档 文档
-
LVGL V8.3: Welcome to the documentation of LVGL! — LVGL documentation
-
LVGL V9.0: 欢迎阅读LVGL(v9.0)中文开发手册! — LVGL 文档
-
LVGL master(当前最新版本): 欢迎阅读LVGL(v9.0)中文开发手册! — 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,代码没有一点优化,大家将就着看吧。
代码文件和工程所用到的文件都在里(大概)