1.使用技巧
第一:子菜单无法直接输入中文的,先输入英文/拼音,后面点击ui设计师正下面的编辑界面,可以修改名字为中文
第二:编辑界面中有两个常用设置
shortcut --》设置快捷键
图标 --》设置子菜单的图标2.子菜单如何使用
方法:使用信号与槽
转到槽函数:在编辑框中右键点击某个子菜单--》选择转到槽
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
//点击新建
void MainWindow::on_actionxinjian_triggered()
{
qDebug()<<"你点击了新建子菜单";
}
QT中的数据库操作
1.涉及到类
QT += sql //在.pro文件中的添加类库
QSqlDatabase --》表示数据库对象
QSqlQuery --》实现数据库的基本操作(增删改查)
数据库驱动:由于市面上主流的数据库软件特别多,QT可以支持市面上所有主流的数据库软件,但是无法判断你的电脑系统中究竟安装的是哪种数据库软件,所以QT就需要你依据你当前系统中安装的数据库软件提前安装对应的驱动2.思路和方法
第一步:安装数据库的驱动
[static] QSqlDatabase QSqlDatabase::addDatabase(const QString &type, const QString &connectionName = QLatin1String(defaultConnection))
返回值:数据库对象(已经安装好对应驱动的)
参数:type --》你要安装的数据库驱动名字
QDB2 IBM公司的数据库驱动
QMYSQL MySQL
QOCI 甲骨文
QODBC 微软
QSQLITE sqlite3
connectionName --》数据库的连接名,当你要同时操作多个不同的数据库文件,就需要用到这个参数
第二步:设置数据库的路径名
void QSqlDatabase::setDatabaseName(const QString &name)
参数: name --》你要使用的数据库路径名
第三步:打开数据库文件
bool QSqlDatabase::open()
第四步:定义QSqlQuery类的对象,操作数据库(新建表格,增删改查)
QSqlQuery::QSqlQuery(QSqlDatabase db)
参数: db --》你要操作的那个数据库对象
bool QSqlQuery::exec(const QString &query)
返回值: 成功true 失败false
参数:query --》你要执行的SQL语句
第五步:关闭数据库
void QSqlDatabase::close()3.扩展方法
(1)获取数据库操作过程中产生的错误信息
QSqlError QSqlDatabase::lastError() const
返回值: QSqlError --》保存产生的错误信息
QString QSqlError::text() const //把产生的错误信息以字符串的形式返回
(2)调用查询命令的时候,如何获取查询结果
bool QSqlQuery::next() //遍历查询结果
返回值:如果查询有结果--》返回true
查询没有结果--》返回false
while(query.next())
{
打印查询结果
}
QVariant QSqlQuery::value(int index) const
返回值: 你这个字段对应的值
参数: index --》字段的索引号,从0开始
比如:name 0
author 1
、 price 2
QVariant QSqlQuery::value(const QString &name) const
返回值: 你这个字段对应的值
参数: name --》字段的名字
比如:name
author
、 price
(3)QVariant类是QT中的万能数据类型(通用数据类型)
情况一:其它类型---》转成QVariant对象
QVariant提供了大量的构造函数--》可以把其它数据类型转成QVariant类的对象
情况二:QVariant对象---》转成其它类型
QVariant提供了大量的toxxxx()方法进行转换4.操作多个表格,操作多个数据库文件
操作多个表格:只需要依据表格的名字去区分不同的表格(因为所有的SQL语句操作表格的时候都需要使用到表格的名字)
操作多个数据库文件:必须在安装数据库驱动的时候,通过数据库连接名去区分不同的数据库文件
base1=QSqlDatabase::addDatabase("QSQLITE","haha"); //第二个参数就是数据库连接名
base2=QSqlDatabase::addDatabase("QSQLITE","hehe"); //第二个参数就是数据库连接名
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//设置表格列表框的列数
ui->tableWidget->setColumnCount(3);
//设置字段名
ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"书名"<<"作者"<<"价格");
//设置行数
ui->tableWidget->setRowCount(10);
//安装数据库的驱动
mybase=QSqlDatabase::addDatabase("QSQLITE");
//设置数据库文件的路径名
mybase.setDatabaseName("./1.db");
//打开数据库文件
bool ret=mybase.open();
if(!ret)
{
qDebug()<<"打开数据库文件失败,失败原因: "<<mybase.lastError().text();
return;
}
//往数据库文件中新建一个书籍表格
QSqlQuery query(mybase);
ret=query.exec("create table if not exists booktable (name text,author text,price float);");
if(!ret)
{
qDebug()<<"新建表格失败,失败的原因: "<<query.lastError().text();
return;
}
}
MainWindow::~MainWindow()
{
delete ui;
}
//插入书籍信息
void MainWindow::on_insertbt_clicked()
{
bool ret;
//获取输入的内容
QString name=ui->namele->text();
QString author=ui->authorle->text();
QString price=ui->pricele->text();
//拼接得到完整的插入语句
QString cmd=QString("insert into booktable values (\"%1\",\"%2\",%3);").arg(name).arg(author).arg(price.toDouble());
QSqlQuery query(mybase);
ret=query.exec(cmd);
if(!ret)
{
qDebug()<<"插入数据失败,失败的原因: "<<query.lastError().text();
return;
}
}
//查询书籍信息
void MainWindow::on_findbt_clicked()
{
bool ret;
int i=0,j;
//清空表格列表框
ui->tableWidget->clear();
//获取要查询的书籍名字
QString findname=ui->findnamele->text();
//判断要查询的书籍名字是否为空字符串
if(findname.isEmpty()) //说明用户没有输入要查询的书籍名字
{
QSqlQuery query(mybase);
ret=query.exec("select * from booktable;");
if(!ret)
{
qDebug()<<"查询数据失败,失败的原因: "<<query.lastError().text();
return;
}
//遍历查询结果
while(query.next())
{
//打印查询结果
//qDebug()<<"名称: "<<query.value(0).toString();
//qDebug()<<"作者: "<<query.value(1).toString();
//qDebug()<<"价格: "<<query.value(2).toString();
// qDebug()<<"名称: "<<query.value("name").toString();
// qDebug()<<"作者: "<<query.value("author").toString();
// qDebug()<<"价格: "<<query.value("price").toString();
//在表格列表框中显示结果
for(j=0; j<3; j++)
{
QString str=query.value(j).toString();
QTableWidgetItem *item=new QTableWidgetItem(str);
ui->tableWidget->setItem(i,j,item);
}
i++;
}
}
else //说明用户有输入书籍名称
{
QSqlQuery query(mybase);
QString cmd=QString("select * from booktable where name=\"%1\";").arg(findname);
ret=query.exec(cmd);
if(!ret)
{
qDebug()<<"查询数据失败,失败的原因: "<<query.lastError().text();
return;
}
//遍历查询结果
while(query.next())
{
//打印查询结果
//qDebug()<<"名称: "<<query.value(0).toString();
//qDebug()<<"作者: "<<query.value(1).toString();
//qDebug()<<"价格: "<<query.value(2).toString();
// qDebug()<<"名称: "<<query.value("name").toString();
// qDebug()<<"作者: "<<query.value("author").toString();
// qDebug()<<"价格: "<<query.value("price").toString();
//在表格列表框中显示结果
for(j=0; j<3; j++)
{
QString str=query.value(j).toString();
QTableWidgetItem *item=new QTableWidgetItem(str);
ui->tableWidget->setItem(i,j,item);
}
i++;
}
}
}
QT中操作多个不同的数据库文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
bool ret;
//安装数据库的驱动
base1=QSqlDatabase::addDatabase("QSQLITE","haha");
base2=QSqlDatabase::addDatabase("QSQLITE","hehe");
//设置数据库文件的路径名
base1.setDatabaseName("./1.db");
base2.setDatabaseName("./2.db");
//打开数据库文件
ret=base1.open();
if(!ret)
{
qDebug()<<"打开base1失败!";
return;
}
ret=base2.open();
if(!ret)
{
qDebug()<<"打开base2失败!";
return;
}
//往base1里面新建表格
QSqlQuery query1(base1);
query1.exec("create table stutable (name text,age int);");
//往base2里面新建表格
QSqlQuery query2(base2);
query2.exec("create table stutable (name text,age int);");
}
MainWindow::~MainWindow()
{
delete ui;
}
补充说明:
1.C/C++中
基本数据类型
数组
容器 --》内存存放
以上存储方式都有一个共同特点:程序退出以后数据就消失了,无法永久保存数据
为了实现数据的永久存储(存放在硬盘中,文件的形式存放)--》利用文件IO的知识,读写文件保存数据
数据库:数据的仓库,也是用来存放数据,实现数据增删改查(以数据库文件的形式存放硬盘中)
数据库使用SQL语句去操作数据
SQL语句: 结构查询语言
2.市面上主流的数据库软件
甲骨文oracle --》
微软 --》SQLserver
IBM --》DB
瑞典 --》MySql
嵌入式开发 --》sqlite3 小型的(大概几十万条数据的存储),开源的数据库软件
sqlite3下载和移植
1.下载
百度搜索sqlite3官网,直接点击download下载2.移植
移植:把别人提供的开源的代码,通过特定的编译工具编译成目标平台需要用到库文件/头文件/可执行程序
移植三部曲:
第一步:执行configure脚本,自动生成Makefile
一般来说网上提供的开源库,都有configure这个脚本
第二步:执行make,生成可执行程序
第三步(可选):执行make install(把编译得到的库文件/头文件/可执行程序安装到你指定的目录路径下)
如果你直接照着下面的笔记移植,会发现方向键无法使用
解决方法:先在ubuntu中安装libreadline-dev这个插件,然后再去移植sqlite3即可解决问题
sudo apt-get install libreadline-dev
(1)移植X86平台的
(1)把下载的压缩包拷贝到家目录,解压
tar -zxf sqlite-autoconf-3370200.tar.gz
(2)进入解压目录,执行configure,会自动生成Makefile
./configure
(3)执行make命令,自动编译程序
(2)移植ARM平台的
(1)把下载的压缩包拷贝到家目录,解压
tar -zxf sqlite-autoconf-3370200.tar.gz
(2)进入解压目录,执行configure,会自动生成Makefile(使用的是arm版本的编译工具)
./configure --host=arm-linux
--host 用来指定目标平台是ARM平台
(3)执行make命令,自动编译程序
(4)把第三步编译产生的sqlite3下载到开发板的/bin,修改权限为777即可使用
使用sqlite3
1.进入sqlite3的命令行模式
数据库文件:以.db结尾的一种文件格式,是用来存放数据的,属于数据库类型的文件
进入命令模式: ./sqlite3 xxx.db
SQLite version 3.37.2 2022-01-06 13:25:41 //版本,发布时间
Enter ".help" for usage hints. //输入.help命令查看使用帮助
sqlite>2.sqlite3的内置命令
内置命令:sqlite3这个软件程序本身自带的命令
内置命令都是小数点开头,后面不需要写分号
.help 查看所有的内置命令
.quit 退出sqlite3
.exit 退出sqlite3
.tables 查看当前数据库文件中所有表格的名字3.sqlite3中的数据类型
bit 二进制0/1
tinyint 8位的整数
smallint 16位整数
int 32位整数
float 32位小数
real 类似于double
char[] 表示字符串
text 文本类型,也能表示字符串
常用的SQL语句--》实现数据库的增删改查基本操作
SQL语句: 结构查询语言
SQL语句的作用和特点:
作用:辅助我们实现数据的基本操作
特点:简单方便,接近人类的自然语言
它是一种通用的语言,市面上所有的数据库软件都能支持
每一句语句后面都必须有分号结尾
(1)新建表格
表格:数据库文件(.db结尾)中的数据都是以表格的形式存储的
学生表格:
字段名: 姓名 年龄 成绩
张三 18 85
李四 14 78
create table 表的名字 (字段名1 修饰词,字段名2 修饰词.........);
比如:create table stutable (name char[10],age int,score float);
//使用unique修饰字段,让这个字段具有唯一性
比如:create table stutable (name char[10],age int,id text unique); //实现的效果就是:id不能有重复的,其他字段可以重复
//使用not null修饰字段,让这个字段不允许插入空值
比如:create table stutable (name text not null,age int,phonenum text unique); //限制name这个字段不能传递空值
//使用if not exists子句判断表格是否存在
表格名字存在--》就不创建了
表格名字不存在--》就创建一个
同一个数据库文件中不能出现名字一样的表格
比如:create table if not exists stutable (name char[10],age int,score float);(2)往表格中插入数据
insert into 表的名字 values (字段1对应的值,字段2对应的值......);
比如:insert into stutable values ("张三",18,85.5);(3)查询表格中的数据
select * from 表的名字 // *表示查询表格中所有的字段信息
比如:select * from stutable;
select name,score from 表的名字 //只想查看name和score两个字段
比如:select name from stutable;
select name,score from stutable;
select * from 表的名字 where 条件; //带条件的查询,用到了where子句
比如:select * from stutable where score>=80;
select * from stutable where score>=80 and score<=90; //多个条件同时满足,使用and
select * from stutable where score>=80 or name="张三"; //多个条件满足其中一个,使用or
select * from 表的名字 where name like "张%"; //like语句用来模糊匹配字符串
比如:select * from stutable where name like "张%";
select * from stutable where name like "%建%";
select * from stutable where name like "%军";
select * from 表的名字 order by age desc; //order by子句用来排序,desc表示降序
select * from 表的名字 order by age asc; //order by子句用来排序,asc表示升序
比如:select * from stutable order by age desc;
select * from stutable order by age asc;(4)删除表格中的数据
delete from 表的名字 where 条件;
比如:delete from stutable where age=17;
drop table 表的名字; //删除整个表格(5)修改表格中的数据
update 表的名字 set 字段=新的值 where 条件;
比如:update teachertable set name="zhangsansan" where name="zhangsan"; //把原来名字是"zhangsan"改成"zhangsansan"
update teachertable set name="lisi",age=18 where name="zhangsansan";
C语言调用sqlite3中的接口函数实现数据库的基本操作
1.接口函数
(1)打开/新建数据库文件
如果数据库文件存在--》打开
如果数据库文件不存在--》新建
int sqlite3_open(
const char *filename,
sqlite3 **ppDb
);
返回值:成功 --》返回SQLITE_OK
失败 --》返回头文件444行定义的某种错误
参数:filename --》你要打开/新建的数据库文件的路径名
ppDb --》数据库的句柄,后面要操作这个数据库,使用这个句柄就可以了
int fd=open("1.txt") 文件描述符--》文件的句柄
(2)操作数据库--》新建表格,实现增删改查操作
int sqlite3_exec(
sqlite3*, //你刚才打开/新建数据库句柄
const char *sql, //你要执行的SQL语句
int (*callback)(void*,int,char**,char**), //函数指针,当你执行查询语句的时候必须传递这个参数
你查询的结果有几条,callback指向的函数就会被自动调用几次
查询没有结果,callback指向的函数就不会调用
void* --》跟第四个参数有关
int --》表格的列数
char** --》查询的具体结果
char** --》字段名
void * //传递给callback的第一个参数
char **errmsg //执行SQL语句产生的错误信息
);
(3)关闭数据库
int sqlite3_close(sqlite3*);
总结:查询/删除的时候,如果数据不存在,你不要有错误的认识(认为查询/删除语句执行错误)2.编译程序
gcc *.c -o main -pthread -ldl
#include <stdio.h>
#include "sqlite3.h" //数据库有关的头文件
int main()
{
sqlite3 *mydb;
char *errmsg;
int ret;
//新建/打开数据库文件
ret=sqlite3_open("./1.db",&mydb);
if(ret!=SQLITE_OK)
{
printf("打开/新建数据库失败,原因请你去头文件444行查看!\n");
return -1;
}
//往数据库文件中新建一个表格
ret=sqlite3_exec(mydb,"create table stutable (name text,age int);",NULL,NULL,&errmsg);
if(ret!=SQLITE_OK)
{
printf("新建表格失败,原因:%s!\n",errmsg);
return -1;
}
}
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h" //数据库有关的头文件
sqlite3 *mydb;
char *errmsg;
int ret;
//定义查询语句需要用到的回调函数
int fun(void *arg,int col,char **str1,char **str2)
{
//printf("fun被调用了!\n");
int i;
printf("你查询的表格总共: %d 列\n",col);
for(i=0; i<col; i++)
{
printf("str1存放:%s\n",*(str1+i));
printf("str2存放:%s\n",*(str2+i));
}
return 0;
}
//插入书籍数据
int insert_book()
{
char cmd[100]={0};
char name[10];
char author[10];
float price;
printf("请输入书籍的名字,作者,价格!\n");
scanf("%s",name);
scanf("%s",author);
scanf("%f",&price);
//拼接得到完整的SQL语句
sprintf(cmd,"insert into booktable values (\"%s\",\"%s\",%f);",name,author,price);
//执行插入语句
ret=sqlite3_exec(mydb,cmd,NULL,NULL,&errmsg);
if(ret!=SQLITE_OK)
{
printf("插入数据失败,原因:%s!\n",errmsg);
return -1;
}
return 0;
}
//删除书籍数据
int delete_book()
{
char name[10];
char cmd[100]={0};
printf("请输入你要删除的书籍名字!\n");
scanf("%s",name);
//拼接得到完整的SQL语句
sprintf(cmd,"delete from booktable where name=\"%s\";",name);
//执行删除语句
ret=sqlite3_exec(mydb,cmd,NULL,NULL,&errmsg);
if(ret!=SQLITE_OK)
{
printf("删除数据失败,原因:%s!\n",errmsg);
return -1;
}
return 0;
}
//修改书籍数据
int update_book()
{
char cmd[100]={0};
char oldname[10];
float newprice;
printf("请输入你要修改的书籍名字!\n");
scanf("%s",oldname);
printf("请输入你修改之后新的价格!\n");
scanf("%f",&newprice);
//拼接得到完整的SQL语句
sprintf(cmd,"update booktable set price=%f where name=\"%s\";",newprice,oldname);
//执行修改语句
ret=sqlite3_exec(mydb,cmd,NULL,NULL,&errmsg);
if(ret!=SQLITE_OK)
{
printf("修改数据失败,原因:%s!\n",errmsg);
return -1;
}
return 0;
}
//查询书籍数据
int find_book()
{
//执行查询语句
ret=sqlite3_exec(mydb,"select * from booktable;",fun,NULL,&errmsg);
if(ret!=SQLITE_OK)
{
printf("查询数据失败,原因:%s!\n",errmsg);
return -1;
}
return 0;
}
int main()
{
int n;
//新建/打开数据库文件
ret=sqlite3_open("./1.db",&mydb);
if(ret!=SQLITE_OK)
{
printf("打开/新建数据库失败,原因请你去头文件444行查看!\n");
return -1;
}
//往数据库文件中新建一个书籍表格
ret=sqlite3_exec(mydb,"create table if not exists booktable (name text,author text,price float);",NULL,NULL,&errmsg);
if(ret!=SQLITE_OK)
{
printf("新建表格失败,原因:%s!\n",errmsg);
return -1;
}
while(1)
{
//打印一个菜单
printf("1.插入书籍数据!\n");
printf("2.删除书籍数据!\n");
printf("3.修改书籍数据!\n");
printf("4.查询书籍数据!\n");
printf("5.退出程序!\n");
scanf("%d",&n);
switch(n)
{
case 1:
insert_book();
break;
case 2:
delete_book();
break;
case 3:
update_book();
break;
case 4:
find_book();
break;
case 5:
sqlite3_close(mydb);
exit(0);
break;
}
}
}