一、前言
程序系统内部的内存存储是在程序关闭后进行自动清除,这对我们记录信息和使用过程都有着极大的影响,若想做出适合平时使用的系统,结合数据库进行系统开发是最普遍和常见的方式
本文通过Qt和SQL进行结合,开发出商品库存管理系统,可以记录商品的总量,剩余量,品牌,类型以及金额,并通过数据库对数据进行存储。
二、基本原理和数据表的设计
Qt中提供的QSqlQuery类适用于连接各种类型的数据库,本文连接的是MySql数据库,出现连接问题参考上文。
数据表结构的设计一定要符合系统需要,本系统设计了类型表和品牌表,结构如下:
类型表 品牌表
Sql语句如下:
create table type(id1 int primary key,name text);
create table brand(id2 int primary key, name text,type text,price int,sum int,sell int,last int);
系统主要使用了QSqlQuery类中的方法与数据库进行联动,同时通过将ui代码载入系统进行本窗体切换不同界面,实现一个窗体完成各种功能。
首先设计不同界面的UI
主体ui界面
查询商品ui界面
ui代码生成如下:
1、打开Qt 5.12.9 for Desktop (MinGW 7.3.0 32 bit)命令行
2、切换到QT项目的路径
3、输入uic-= ui.h widget.ui
(ui文件生成.h头文件)
将生成的文件复制进入主窗体
头文件添加(选择有用的进行复制)
widget文件添加:
此时通过show()和hide()就可以控制窗体的显示和隐藏。
三、具体代码和详细设计
1.初始化
对多个界面进行初始化和隐藏,同时对数据库进行连接操作,同时写入sql语句进行建表和插入数据
void Widget::Init()
{
setSelectForm(this);
setPasssWdForm(this);
wid_select->hide();
wid_password->hide();
QString filename = "test";
QFileInfo info(filename);
bool ret = info.exists();
db = QSqlDatabase::addDatabase("QMYSQL");
db.setDatabaseName(filename);
db.setHostName("localhost");
db.setUserName("root");
db.setPassword("root");
db.setPort(3306);
QSqlQuery query(db);
bool ok = db.open();
if(ok)
{
//创建分类表
QString cmd1 = "create table type(id1 int primary key,name text);";
query.exec(cmd1);
query.exec(QString("insert into type values('0','请选择类型')"));
query.exec(QString("insert into type values('01','电视')"));
query.exec(QString("insert into type values('02','空调')"));
//创建品牌表
QString cmd2 = "create table brand(id2 int primary key, name text,"
"type text,price int,sum int,sell int,last int);";
query.exec(cmd2);
query.exec(QString("insert into brand values('01','海信','电视',3699,50,10,40)"));
query.exec(QString("insert into brand values('02','创维','电视',3499,20,5,15)"));
query.exec(QString("insert into brand values('03','海尔','电视',4199,80,40,40)"));
query.exec(QString("insert into brand values('04','王牌','电视',3999,40,10,30)"));
query.exec(QString("insert into brand values('05','海尔','空调',2899,60,10,50)"));
query.exec(QString("insert into brand values('06','格力','空调',2799,70,20,50)"));
qDebug()<<ok;
}
}
2.数据初始化
读取type数据将其载入combox,同时对自定义的信号进行绑定
void Widget::InitData()
{
QString sel1 = "select name from type";
QSqlQuery query(db);
query.exec(sel1);
QStringList listName;
while(query.next())
{
listName<<query.value("name").toString();
}
ui->cbox_type->addItems(listName);
cbox_select_type->addItems(listName);
connect(cbox_select_type,SIGNAL(currentTextChanged(QString))
,this,SLOT(on_cbox_type_currentTextChanged(QString)));
connect(btn_select_select,SIGNAL(clicked(bool)),this,SLOT(doProcessClickSelect(bool)));
}
3.设定按钮功能
将各个按钮进行槽功能绑定,分别对应隐藏和显示不同的界面,以商品入库和信息查询界面为例
void Widget::on_btn_storage_clicked()
{
wid_select->hide();
wid_password->hide();
ui->wid_sell->show();
ui->lbl_sell->setText("商品入库");
}
void Widget::on_btn_select_clicked()
{
ui->wid_sell->hide();
wid_password->hide();
wid_select->show();
ui->lbl_sell->setText("商品查询");
}
4.商品查询功能
商品查询功能通过商品的品牌和类型对已存商品进行查询
从ui控件中的combox处获取值并加入SQL语句中
QString sel2 = QString("select * from brand where name = '%1' and type='%2'")
.arg(cbox_select_brand->currentText())
.arg(cbox_select_type->currentText());
然后通过append在文本框进行显示信息
query.exec(sel2);
QString msg;
while(query.next())
{
msg+= "品牌名称:"+query.value(1).toString()+"\n";
msg+= "商品类型:"+query.value(2).toString()+"\n";
msg+= "商品价格:"+query.value(3).toString()+"\n";
msg+= "商品总数:"+query.value(4).toString()+"\n";
msg+= "售出数量:"+query.value(5).toString()+"\n";
msg+= "剩余数量:"+query.value(6).toString()+"\n";
}
tedit_select_show->append(msg);
结果如下:
5.类型选择信号的接收
由于初始化只进行了类型的读取,为了使类型和品牌进行联动,定义一个combox中选项改变的信号传入槽中,对选中的类型进行SQL查询并添加到品牌的combox进行显示
void Widget::on_cbox_type_currentTextChanged(const QString &arg1)
{
QSqlQuery query(db);
QString sel2 = QString("select name from brand where type = '%1'").arg(arg1);
query.exec(sel2);
QStringList listProduct;
while(query.next())
{
listProduct<<query.value("name").toString();
}
ui->cbox_brand->clear();
ui->cbox_brand->addItems(listProduct);
cbox_select_brand->clear();
cbox_select_brand->addItems(listProduct);
}
6.商品添加
当点击商品添加的确定按钮时,要对添加的数据进行接收,并通过SQL语句将其传入数据库中,此处可以采用prepare方法,将SQL语句写入prepare方法中,需要替换的数据前面加上":",并通过bindValue()方法进行替换。
if(text == "商品添加")
{
int maxNum = 0;
QSqlQuery query(db);
QString cmd = "select max(id2) from brand";
query.exec(cmd);
if(query.next())
{
maxNum = query.value(0).toString().toInt();
maxNum += 1;
query.prepare("INSERT INTO brand (id2, name, type,price,sum,sell,last) VALUES (:id2, :name, :type,:price,:sum,:sell,:last)");
query.bindValue(":id2", maxNum);
query.bindValue(":name", ui->cbox_brand->currentText());
query.bindValue(":type", ui->cbox_type->currentText());
query.bindValue(":price", ui->ledit_price->text());
query.bindValue(":sum", ui->sbox_num->text());
query.bindValue(":sell", ui->sbox_num->text());
query.bindValue(":last", ui->sbox_num->text());
bool ret = query.exec();
if(ret)
{
QMessageBox::information(this,"提示","保存成功",QMessageBox::Ok);
}
else
{
QMessageBox::information(this,"提示","保存失败",QMessageBox::Ok);
}
}
else
{
return;
}
}
7.商品入库
商品入库功能主要是对已经在库的商品进行数量上的操作,因此通过SQL中的UPDATE进行相对应的操作,同样使用prepare方法,因为入库需要查询相对应的商品,因此通过类型、品牌、价格进行查询判断,并记录下商品的id,未查询到提示用户先进行商品添加。
if(text == "商品入库")
{
int id = 0;
int sum = 0;
int last = 0;
QSqlQuery query(db);
QString type = ui->cbox_type->currentText();
QString brand = ui->cbox_brand->currentText();
QString price = ui->ledit_price->text();
QString cmd = QString("select id2,sum,last from brand where type = '%1' and name = '%2' and price = '%3'").arg(type).arg(brand).arg(price);
query.exec(cmd);
if(query.next())
{
id = query.value(0).toInt();
sum = query.value(1).toInt();
last = query.value(2).toInt();
sum += ui->sbox_num->text().toUInt();
last += ui->sbox_num->text().toUInt();
query.prepare("UPDATE brand SET sum = :sum,last = :last WHERE id2 = :id");
query.bindValue(":sum", sum);
query.bindValue(":last", last);
query.bindValue(":id", id);
bool ret = query.exec();
if(ret)
{
QMessageBox::information(this,"提示","入库成功",QMessageBox::Ok);
}
else
{
QMessageBox::information(this,"提示","入库失败",QMessageBox::Ok);
}
}
else
{
QMessageBox::information(this,"错误","未找到商品",QMessageBox::Ok);
}
}
8.出售商品
出售商品与商品入库操作相似,主要是对已售出商品数量和剩余商品数量进行对应的操作,通过查询商品剩余数量对售出数量进行相应的操作,提示用户商品是否缺货。
if(text == "出售商品")
{
int id,sum,sell,last = 0;
QSqlQuery query(db);
QString type = ui->cbox_type->currentText();
QString brand = ui->cbox_brand->currentText();
QString price = ui->ledit_price->text();
QString cmd = QString("select id2,sum,sell,last from brand where type = '%1' and name = '%2' and price = '%3'").arg(type).arg(brand).arg(price);
bool ret = query.exec(cmd);
if(query.next())
{
id = query.value(0).toInt();
sum = query.value(1).toInt();
sell = query.value(2).toInt();
last = query.value(3).toInt();
if(last>0)
{
int last1 = ui->sbox_num->text().toUInt();
sell += ui->sbox_num->text().toUInt();
if(last>=last1)
{
last -= ui->sbox_num->text().toUInt();
query.prepare("update brand set sell = :sell,last = :last where id2 = :id2");
query.bindValue(":sell",sell);
query.bindValue(":last",last);
query.bindValue(":id2",id);
bool ret = query.exec();
if(ret)
{
QMessageBox::information(this,"提示","售出成功",QMessageBox::Ok);
}
else
{
QMessageBox::information(this,"提示","售出失败",QMessageBox::Ok);
}
}
else
{
QMessageBox::information(this,"提示","商品缺货",QMessageBox::Ok);
}
}
else
{
QMessageBox::information(this,"提示","商品缺货",QMessageBox::Ok);
}
}
}