前言
最近在做关于嵌入式软件的实训项目,主要是设计界面GUI以及代码函数的编写,这个为小组的实训作业,可以在虚拟机上运行,其中gtk来设计图形界面来进行人机交互,sqlite3为数据库的管理系统实现在注册界面的时候将数据输入其中,登录时输入能在数据库中查询到,其中登录和注册功能实现了和sqlite3的交互,进入操作界面后可以对商品进行添加,可以添加商品的id,名称,以及售价进价,利润等等,我这里只构建了3个,还可以添加,能对添加的商品进行删除,修改,能返回登录界面,对于添加的商品我们能完成对他的图片添加,然后点击商品能看到商品的图片。
编译环境
- 电脑:win11 +64位
- 代码编译器:sublime
- 运行环境:本地虚拟机VMware+ubuntu+MobaXterm_Personal_22.1
- 运行说明:在虚拟机VMware上配置相应的环境之后,使用本地文件通过ip地址共享虚拟文件夹。在sublime中打开文件,进行代码的编写,以及保存(必须要保存才能在虚拟机里面编译),然后再sublime中导入sqlite3.c\sqlite3.h的文件和背景图片的再共享文件夹中的同一个路径中,最后在虚拟机上运行或者MobaXterm里面运行都可以。
- 一些编译指令:
gcc xxx.c sqlite3.c -lpthred -ldl pkg-config --cflags --libs gtk±2.0
xxx.c为需要编译的文件
一些sqlite3的编译语言
- sudo sqlite3 *.db //打开指定的数据库
:你需要打开的数据库名称 sqlite3 1000phone.db
注意事项:
1.如果.db的数据库不存在,他会自动帮我们创建一个对应的数据库
2.*任意字符,切记不能出现特殊符号和中文
3.如果数据库存在,则默认打开你需要打开的数据库
4.如果你打开数据后不进行任何操作,默认是临时数据库,不会永久保存- 退出数据库
.q 或者 .exit
注意事项:
1.如果你的sql指令不是以.开头,必须追加;结束标识符,才代表数据库命令输入完成,否则默认是换
行;
2.sql语句不区分大小写,但是指令区分。- 查看数据库
.databases 查看当前数据库的物理地址
没有权限。 在打开数据库的指令前追加 sudo- 查看当前数据库的所有表
.tables
查看当前数据库指定表的表结构
.schema 表的名称
运行的图片
这是登录界面
点击注册时会有另一个界面出来
在这里可以注册用户名和密码,注册之后会显示注册成功
当用户名和密码为空时会报错
接着点击取消回到登录界面进行账户的登录
之后会进入操作界面
在这个界面可以进行商品id的添加、商品名称的添加,商品售价的添加,还可以添加其他的东西,可以在sublime中自己添加。
每添加完一行数据可以点击行进行拍照,将照片以一个界面的形式显示出来,拍照的命名以商品的id为准,这样在点击某一行时才知道点击的哪一行然后弹出一个窗口显示图片。
点击拍照,命名以商品Id,然后点击拍照就行了,拍的照片在当你点击那一行的时候出现
这就是这个项目所能完成的功能。
代码
下面的是一些界面的函数,调用:
这是登录界面的一个函数
//函数名:windows_SMMS_Sign_in_init
//函数功能:登录界面初始化
//函数参数:无
//返回值:无
void windows_SMMS_Sign_in_init(void)
{
windows_sign_in = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request(windows_sign_in, 600, 400);
table_title = gtk_table_new(3, 3, TRUE);
GtkWidget* table_username = gtk_table_new(3, 6, TRUE);
gtk_table_attach_defaults(GTK_TABLE(table_title), table_username, 1, 3, 1, 2);
GtkWidget* table_sign_in = gtk_table_new(2, 6, TRUE);
gtk_table_attach_defaults(GTK_TABLE(table_username), table_sign_in, 1, 5, 2, 3);
GtkWidget* labe_sign_in_id = gtk_label_new("用户名:");
set_label_font_size_and_color(labe_sign_in_id, 12, "black");
gtk_table_attach_defaults(GTK_TABLE(table_username), labe_sign_in_id, 1, 2, 0, 1);
GtkWidget* labe_sign_in_password = gtk_label_new("密码:");
set_label_font_size_and_color(labe_sign_in_password, 12, "black");
gtk_table_attach_defaults(GTK_TABLE(table_username), labe_sign_in_password, 1, 2, 1, 2);
//创建图片
GtkWidget* image_title = gtk_image_new_from_pixbuf(NULL); // 创建图片控件
load_image(image_title, "./picture/cat01.jpg", 75, 300);
gtk_table_attach_defaults(GTK_TABLE(table_title), image_title, 0, 1, 0, 3); // 把图片控件加入布局
GtkWidget* image_sign_in_id = gtk_image_new_from_pixbuf(NULL); // 创建图片控件
load_image(image_sign_in_id, "./picture/name.png", 70, 30);
gtk_table_attach_defaults(GTK_TABLE(table_username), image_sign_in_id, 1, 2, 0, 1); // 把图片控件加入布局
GtkWidget* image_sign_in_password = gtk_image_new_from_pixbuf(NULL); // 创建图片控件
load_image(image_sign_in_password, "./picture/password.png", 70, 30);
gtk_table_attach_defaults(GTK_TABLE(table_username), image_sign_in_password, 1, 2, 1, 2); // 把图片控件加入布局
//行编辑
entry_sign_in_id = gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table_username), entry_sign_in_id, 2, 5, 0, 1);
entry_sign_in_password = gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table_username), entry_sign_in_password, 2, 5, 1, 2);
gtk_entry_set_visibility(GTK_ENTRY(entry_sign_in_password), FALSE);
//按钮
GtkWidget* button_sign_in = gtk_button_new_with_label("登录");
gtk_table_attach_defaults(GTK_TABLE(table_sign_in), button_sign_in, 2, 3, 1, 2);
//gtk_button_set_relief(GTK_BUTTON(button_sign_in), GTK_RELIEF_NONE);
GtkWidget* button_register = gtk_button_new_with_label("注册");
gtk_table_attach_defaults(GTK_TABLE(table_sign_in), button_register, 4, 5, 1, 2);
//gtk_button_set_relief(GTK_BUTTON(button_register), GTK_RELIEF_NONE);
//将表格加入到窗口中
gtk_container_add(GTK_CONTAINER(windows_sign_in), table_title);
//设置背景图片
//set_background(windows_sign_in, 600, 400, "./picture/background.png");
set_background(windows_sign_in, 600, 400, "./images/cat01.jpg");
//信号连接
g_signal_connect(button_sign_in, "pressed", G_CALLBACK(sign_in_callback), NULL);//
g_signal_connect(button_register, "pressed", G_CALLBACK(register_callback), NULL);//
}
下面这个是操作界面的界面设计函数
void snack_main_init(void) //初始化主界面
{
snack_main = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(snack_main),"馋嘴猫儿智能零食柜");//GtkWindow < GtkWidget
gtk_widget_set_size_request(snack_main,750,540);//设置窗口大小
gtk_window_set_resizable(GTK_WINDOW(snack_main),TRUE); //是否可以改变窗口大小
gtk_window_set_position(GTK_WINDOW(snack_main),GTK_WIN_POS_CENTER_ALWAYS);
//添加图片
change_background(snack_main,750,540,"./images/cat03.jpg");
//设计一个表格布局方式
//显示控件,窗口
//添加控件,按钮
GtkWidget * button_add = gtk_button_new_with_label("添加商品");
GtkWidget * button_paizhao = gtk_button_new_with_label("拍照");
///返回按钮
GtkWidget * button_back = gtk_button_new_with_label("返回");
GtkWidget * button_delete = gtk_button_new_with_label("删除商品");
//创建行编辑
entry_id = gtk_entry_new();
entry_name = gtk_entry_new();
entry_price = gtk_entry_new();
//entry_inventory = gtk_entry_new();
gtk_entry_set_max_length(GTK_ENTRY(entry_id), 100); // 设置行编辑显示最大字符的长度
gtk_entry_set_visibility(GTK_ENTRY(entry_id), TRUE); // 明文模式
//添加12x12布局容器
GtkWidget * table = gtk_table_new(12, 12, TRUE);
gtk_container_add(GTK_CONTAINER(snack_main), table); // 容器加入窗口
gtk_table_attach_defaults(GTK_TABLE(table), button_add, 1, 4, 1, 2);// 把按钮加入布局
gtk_table_attach_defaults(GTK_TABLE(table), button_paizhao, 1, 4, 2, 3);// 把按钮加入布局
gtk_table_attach_defaults(GTK_TABLE(table), button_back, 1, 4, 3, 4);
gtk_table_attach_defaults(GTK_TABLE(table), button_delete, 1, 4, 4, 5);// 把按钮加入布局
gtk_table_attach_defaults(GTK_TABLE(table), entry_id, 1, 2, 10, 12);// 把行编辑加入布局
gtk_table_attach_defaults(GTK_TABLE(table), entry_name, 2, 3, 10, 12);
gtk_table_attach_defaults(GTK_TABLE(table), entry_price, 3, 4, 10, 12);
//gtk_table_attach_defaults(GTK_TABLE(table), entry_inventory, 5, 6, 10, 12);
//创建滚动窗口
GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
gtk_table_attach_defaults(GTK_TABLE(table), scrolled_window, 5, 10, 0, 12);// 把滚动窗口加入布局
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gchar *titles[4] = {"商品ID", "商品名称", "商品售价" ,"商品"};
clist = gtk_clist_new_with_titles(3, titles);// 创建GtkCList构件,6列
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), clist);// 将GtkCList构件添加到滚动窗口构件中
/* 设置某列内容显示的对齐方式
* GTK_JUSTIFY_LEFT: 列中的文本左对齐。
*
*
*
* GTK_JUSTIFY_RIGHT: 列中的文本右对齐。
* GTK_JUSTIFY_CENTER:列中的文本居中对齐。
* GTK_JUSTIFY_FILL: 文本使用列中所有可用的空间
*/
gtk_clist_set_column_justification(GTK_CLIST(clist), 0, GTK_JUSTIFY_CENTER);
// 很重要的一点,我们可以设置列宽,让文本能容纳在列中。
gtk_clist_set_column_width(GTK_CLIST(clist), 0, 150);//??????怎么设置的?
database_read();//在snack窗口初始化时,在数据库中读出数据,显示在列表栏中
//监听按钮的信号
g_signal_connect(entry_id, "activate", G_CALLBACK(entry_callback), entry_id);
g_signal_connect(entry_name, "activate", G_CALLBACK(entry_callback), entry_name);
g_signal_connect(entry_price, "activate", G_CALLBACK(entry_callback), entry_price);
//g_signal_connect(entry_inventory, "activate", G_CALLBACK(entry_callback), entry_inventory);
g_signal_connect(button_add, "clicked", G_CALLBACK(add_callback), (gpointer)clist);
g_signal_connect(button_delete, "clicked", G_CALLBACK(delete_callback), (gpointer)clist);
g_signal_connect(button_paizhao, "clicked", G_CALLBACK(window_paizhao), NULL);
//点击返回,回到主界面
g_signal_connect(button_back, "clicked", G_CALLBACK(window_back), NULL);
g_signal_connect(clist, "select-row", G_CALLBACK(select_callback), NULL);
g_signal_connect(clist, "unselect-row", G_CALLBACK(unselect_callback), NULL);
gtk_widget_show_all(snack_main);
gtk_widget_show(snack_main);
g_signal_connect(snack_main,"destroy",G_CALLBACK(gtk_main_quit),NULL);//结束程序
}
整体的代码有个1000多行,很大这里就不一一展示出来了,需要的可以自行下载。
结尾
这其中其实还是有一些问题的,没有修改,但大体的功能还是能实现的,有感兴趣的可以下载文件自行修改一哈,对于gtk配置摄像头的配置环境,也传了文件可以学习,最后这个项目还是肝了几个晚上的,希望能点赞和收藏。😍😁