Qt实现图书管理系统(C++)

文章目录

  • 数据库表的实现
      • 创建表
      • 将powerDesigner里面的表导出成xxx.sql脚本
      • 将SQL文件导入数据库创建表
  • 图书管理系统思维导图
  • 创建工程
  • 开发阶段
        • 创建Dlg_login登录页面
        • login页面样式
        • 主页页面布局
        • 主函数测试login
        • 设置logo
        • 打包程序
        • 子页面的样子
        • 将子页面放到StackedWidget里面
        • 按钮直接形成互斥效果
      • 用属性选择器来改变样式
        • 设置user页面的标头和设置文本不可编辑
  • 创建SqlMgr类进行SQL操作
      • 初始化数据库
    • 登录功能login
    • 用户功能
      • getUsers功能
      • 导入用户(导入文件里面的数据到数据库)
      • 删除用户(del)
      • 搜索用户
    • 图书管理功能
      • 获取图书
      • 添加图书
      • 修改图书
      • 删除图书
        • 遇到的错误
      • 借阅图书
      • 搜索图书
    • 借阅记录管理功能
      • 获取借阅记录
      • 模糊查询记录
      • 归还图书
        • 出现的问题
      • 清空借阅记录
      • 登录功能
      • 页面展示

数据库表的实现

使用powerdesigner工具

创建表

在这里插入图片描述

创建三个表
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

将powerDesigner里面的表导出成xxx.sql脚本

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此时就会生成文件在桌面了
在这里插入图片描述

将SQL文件导入数据库创建表

在这里插入图片描述

在这里插入图片描述
运行sql文件
在这里插入图片描述
设置主键自增

图书管理系统思维导图

在这里插入图片描述

创建工程

在qt上创建一个工程项目

在这里插入图片描述

把这个四个文件发到controller文件夹下,在创建一个dao文件夹

在这里插入图片描述

controller文件夹下面是一些界面类和逻辑类,dao文件夹下就是和数据库交互的

在这里插入图片描述

进入项目

在这里插入图片描述
在这里插入图片描述

加上这一句话

include($$PWD/controller/controller.pri)
正在右键项目执行qmake
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

添加一句这个以后生成的目标文件都在这里(当前文件目录的上一级创建一个bin 文件夹

在这里插入图片描述

开发阶段

创建Dlg_login登录页面

在这里插入图片描述

在这里插入图片描述

login页面样式

QLabel#le_title{font:38px '方正姚体';}
QLabel#name,QLabel#pwd{font: 18px '楷体';}
QLineEdit{border-radius:4px;min-height:25px;border:1px solid gray;}
QPushButton{border-radius:4px;background-color:#409eff;color:white;font-size:18px;}
QWidget#bg{background:white;}

主页页面布局

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

主函数测试login

int main(int argc, char *argv[])
{QApplication a(argc, argv);//实现登录Dlg_login dlg;int ret=dlg.exec();if(1==ret){Cell_main w;w.show();return a.exec();}if(0==ret){exit(0);return 0;}return 0;}

实现Dlg_login函数

void Dlg_login::on_btn_login_clicked()
{setResult(1);this->hide();
}void Dlg_login::on_btn_exit_clicked()
{setResult(0);this->hide();
}

设置logo

在这里插入图片描述
在资源文件中添加一个app.rc文件,在打开这个app.rc文件 添加一句话:

IDI_ICON1 ICON DISCARDABLE “tubiao.ico”
再把这个ico图标放到这个资源文件里

在这里插入图片描述

打包程序

在这里插入图片描述
如果还 运行不了,可能是有些库没有权限没靠过来,手动考
在这里插入图片描述

子页面的样子

用户管理界面
图书管理页面
借阅管理

将子页面放到StackedWidget里面

在这里插入图片描述

#include "cell_main.h"
#include "ui_cell_main.h"
#include"dlg_login.h"
#include"QPushButton"
#include"QDebug"Cell_main::Cell_main(QWidget *parent): QMainWindow(parent), ui(new Ui::Cell_main),m_bookPage(nullptr),m_recordPage(nullptr),m_userPage(nullptr)
{ui->setupUi(this);//初始化栈窗口initPage();}
void Cell_main::initPage()
{m_bookPage=new cell_BookMgr(this);m_userPage=new cell_UserMgr(this);m_recordPage=new cell_Record(this);//把页面放到栈窗口ui->stackedWidget->addWidget(m_userPage);ui->stackedWidget->addWidget(m_bookPage);ui->stackedWidget->addWidget(m_recordPage);//设置首页是用户管理ui->stackedWidget->setCurrentIndex(0);qDebug()<<"helloworld";auto l=ui->tool->children();//获得子控件for(auto it:l){//为每个页面进行绑定槽函数if(it->objectName().contains("btn")){connect(static_cast<QPushButton*>(it),&QPushButton::clicked,this,&Cell_main::DealMenu);}}//主页初始化一下// m_userPage->initPage();}void Cell_main::DealMenu()
{auto str=sender()->objectName();//切换页面do{if("btn_user"==str){//m_userPage->initPage();ui->stackedWidget->setCurrentIndex(0);break;}if("btn_book"==str){//m_bookPage->initPage();ui->stackedWidget->setCurrentIndex(1);break;}if("btn_his"==str){//m_recordPage->initPage();ui->stackedWidget->setCurrentIndex(2);break;}}while(false);}Cell_main::~Cell_main()
{delete ui;
}

在添加完之后在进行切换操作,页面之间切换
在这里插入图片描述

按钮直接形成互斥效果

在这里插入图片描述

用属性选择器来改变样式

在这里插入图片描述
在这里插入图片描述

设置user页面的标头和设置文本不可编辑

  ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);//一次选中一行ui->tableView->setModel(&m_model);ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);//设置不可编辑m_model.setHorizontalHeaderLabels(QStringList{"用户id","年级","部门","权限","人物类型","密码","用户名"});

在这里插入图片描述

创建SqlMgr类进行SQL操作

涉及到的函数函数和变量

class SqlMgr
{
public:SqlMgr();//设置单例模式static SqlMgr*  instance;static SqlMgr*  getInstance(){if(nullptr==instance){instance=new SqlMgr();}return instance;}void test1();void init();//初始化数据库//登录bool login(QString username,QString password,int &userId);//获取所有用户QVector<QStringList> getUsers(QString StrCondition="");//添加用户void addUsers(QVector<QStringList> );//删除用户void delUser(QString userId);//获取所有图书QVector<QStringList> getBooks(QString StrCondition="");//添加图书void addBooks(QVector<QStringList> );//修改图书void updateBook(QStringList);//删除图书QString delBook(QString bookId);//归还图书QString returnBook(QString userId,QString bookId);//图书借阅QString borrowBook(QString userId,QString bookId);//获取借阅记录QVector <QStringList> getRecord(QString strCondition="");//清除借阅记录void clearRecord();//private:QSqlDatabase m_db;

初始化数据库

void SqlMgr::init()
{m_db=QSqlDatabase::addDatabase("QSQLITE");m_db.setDatabaseName(QCoreApplication::applicationDirPath()+"/db/WpcBook.db");qDebug()<<m_db.open();
}

在这里插入图片描述
失败啦!!!
在这里插入图片描述
成功啦,失败原因是之前把一些文件打包到bin目录下了,所以就不走系统的了缺少一些文件就会报错,把bin目录下的文件删除就走系统的了
在这里插入图片描述

m_db.setDatabaseName(QCoreApplication::applicationDirPath()

app目录是这个路径

这里是引用

登录功能login

先不实现键盘输入登录功能,先测试一下,查询数据库里面是否有这个用户,有就返回true

//返回      true登录成功
bool SqlMgr::login(QString username, QString password)
{QSqlQuery q(m_db);QString sql=QString("select *from user where username='%1' and password='%2'").arg(username).arg(password);bool ret=q.exec(sql);//执行查询语句 执行成功返回trueif(ret==false){qDebug()<<q.lastError();}return ret;
}

用户功能

getUsers功能

(数据库层)SqlMgr代码:

//获取所有用户
QVector<QStringList> SqlMgr::getUsers(QString StrCondition){QSqlQuery q(m_db);//StrCondition里可以写模糊查询的东西QString sql=QString("select *from user %1").arg(StrCondition);//获取到的数据可能是多行QVector<QStringList> vec;bool ret=q.exec(sql);if(ret==false){qDebug()<<q.lastError();}else{//读取返回来的数据//获取这个数据是几行int col =q.record().count();QStringList temp;while(q.next()){//向下读temp.clear();for(int i=0;i<col;i++){//将这一行数据转换为QString放到temp<<q.value(i).toString();}vec.push_back(temp);}qDebug()<<"sqlMgr getuser被执行";}return vec;}

(控制层代码)cell_UserMgr:

//初始化用户管理页面
void cell_UserMgr::initPage(QString strCondition){qDebug()<<"initUSer被执行";//调用数据库进行查询QVector<QStringList>vec= SqlMgr::getInstance()->getUsers(strCondition);m_model.clear();//在设置一次头m_model.setHorizontalHeaderLabels(QStringList{"用户id","年级","部门","权限","人物类型","密码","用户名"});QList <QStandardItem*>items;//添加到页面//获取每一个QStringListfor(QStringList tempList:vec){items.clear();//清理for(int i=0;i<tempList.size();i++){//追加每一个元素items.append(new QStandardItem(tempList[i]));}//追加到一行上面m_model.appendRow(items);}}

在这里插入图片描述

导入用户(导入文件里面的数据到数据库)

使用: QFileDialog::getOpenFileName(nullptr,“输入文件路径”);会出现弹窗

**dao代码(SqlMgr) **

//导入用户(.txt类型 是GBK编码)
void SqlMgr::addUsers(QVector<QStringList> vec){QSqlQuery q(m_db);//StrCondition里可以写模糊查询的东西//一个个拿出来for(auto tempList:vec){QString sql=QString("insert into user VALUES(NULL,'%1','%2','%3','%4','%5','%6')").arg(tempList[0]).arg(tempList[1]).arg(tempList[2]).arg(tempList[3]).arg(tempList[4]).arg(tempList[5]);bool ret=q.exec(sql);if(ret==false){qDebug()<<q.lastError();}}}

控制层代码:

//导入用户
void cell_UserMgr::on_btn_UserAdd_clicked()
{//会弹出页面窗口auto strPath=QFileDialog::getOpenFileName(nullptr,"输入文件路径");QVector<QStringList>vec;if(strPath.isEmpty()!=true){QFile f(strPath);//读这个文件qDebug()<<"路径: "<<strPath;f.open(QFile::ReadOnly);while(!f.atEnd()){QByteArray bytes= f.readLine();//一次读一行//转换为QString 里面的数据类型是 : xxx,xxx,xxx,xxx用,分割QString str(bytes);qDebug()<<"str = "<<str;//分割QStringList  strList=str.split(",");//判断if(strList.size()!=6){QMessageBox::information(nullptr,"信息","导入失败",QMessageBox::Ok);return;}//把一行数据的最后的元素的最后两个字节去掉\n\r去掉strList[strList.size()-1]=strList[strList.size()-1].chopped(2);//存vec.push_back(strList);}//调用数据库SqlMgr::getInstance()->addUsers(vec);f.close();//刷新页面//ui->le_search->clear();initPage();}
}

在这里插入图片描述
先写数据层库层

效果:
在这里插入图片描述

删除用户(del)

数据库:

void SqlMgr::delUser(QString userId){QSqlQuery q(m_db);QString sql=QString("delete from user where id= %1").arg(userId);bool ret=q.exec(sql);if(!ret){qDebug()<<q.lastError().text();}}

控制层:

//删除用户
void cell_UserMgr::on_btn_UserDel_clicked()
{//获取鼠标点击到的哪一行的//第一列的数据int r=ui->tableView->currentIndex().row();//获取当前行号if(r<0){QMessageBox::information(nullptr,"提示","请选中一行...",QMessageBox::Ok);}else{//获取r行 的0列auto id=m_model.item(r,0)->text();SqlMgr::getInstance()->delUser(id);//刷新页面initPage();}
}

搜索用户

控制层:(直接调用initPage函数)

    void cell_UserMgr::on_le_search_textChanged(const QString &arg1){QString sql=QString("where username like '%%1%' or department like '%%1%'").arg(arg1);initPage(sql);}

在这里插入图片描述

图书管理功能

获取图书

数据库:

//获取图书
QVector<QStringList> SqlMgr::getBooks(QString StrCondition)
{QSqlQuery q(m_db);QString sql=QString("select *from book %1").arg(StrCondition);QVector<QStringList> vec;//执行bool ret=q.exec(sql);if(!ret){qDebug()<<q.lastError().text();}else{QStringList strList;//获取这些数据有几列int col=q.record().count();//从q里面获取数据while(q.next()){strList.clear();for(int i=0;i<col;i++){//把这一行数据放进去strList<<q.value(i).toString();}vec.push_back(strList);}}return vec;}//添加图书
void SqlMgr::addBooks(QVector<QStringList> vec ){//添加图书是一次添加一本QSqlQuery q(m_db);auto data= vec[0];QString sql=QString("insert into Wbook values(null,'%1','%2','%3','%4','%5',%6,'');").arg(data[1]).arg(data[2]).arg(data[3]).arg(data[4]).arg(data[5]).arg(data[6]);bool ret=q.exec(sql);//执行查询语句if(ret==false){qDebug()<<q.lastError();return;}
}

控制层:

//初始化图书管理页面
void cell_BookMgr::initPage(QString condition){//调用dao的getbooksauto vec=SqlMgr::getInstance()->getBooks(condition);//拿数据显示到页面m_model.clear();//在设置一次头m_model.setHorizontalHeaderLabels(QStringList{"图书id","图书名称","价格","类型1","类型2","类型3","数量","图片"});for(QStringList tlist:vec){//拿出一行QStringListQList<QStandardItem*> items;for(int i=0;i<tlist.size();i++){//追加到itemsitems.append(new QStandardItem(tlist[i]));}qDebug()<<"图书被调用";//加到modelm_model.appendRow(items);}}

添加图书

添加图书要弹出一个页面Dlg_addOrUp

在这里插入图片描述
数据库层:

//添加图书
void SqlMgr::addBooks(QStringList data ){//添加图书是一次添加一本QSqlQuery q(m_db);QString sql=QString("insert into book values(null,'%1','%2','%3','%4','%5',%6,'');").arg(data[0]).arg(data[1]).arg(data[3]).arg(data[4]).arg(data[5]).arg(data[2]);bool ret=q.exec(sql);//执行查询语句if(ret==false){qDebug()<<q.lastError().text();}
}

控制层:

void cell_BookMgr::on_btn_bookAdd_clicked()
{//调用子窗口Dlg_addOrUp dlg;dlg.setFlag(-1);//添加就设置为-1dlg.exec();}

Dlg_addOrUp类

#include "dlg_addorup.h"
#include "ui_dlg_addorup.h"
#include"dao/sqlmgr.h"
#include"QDebug"
Dlg_addOrUp::Dlg_addOrUp(QWidget *parent) :QDialog(parent),ui(new Ui::Dlg_addOrUp)
{ui->setupUi(this);}Dlg_addOrUp::~Dlg_addOrUp()
{delete ui;
}void Dlg_addOrUp::addOrUp()
{QStringList strList;//添加if(m_flag==-1){//获取页面输入strList<<ui->le_name->text();strList<<ui->le_press->text();strList<<ui->le_count->text();strList<<ui->cb1->currentText();strList<<ui->cb2->currentText();strList<<ui->cb3->currentText();qDebug()<<"==== "<<strList;//调用数据添加函数SqlMgr::getInstance()->addBooks(strList);}
}void Dlg_addOrUp::setFlag(int flag)
{m_flag=flag;
}void Dlg_addOrUp::on_btn_ok_clicked()
{addOrUp();//隐藏页面this->hide();
}void Dlg_addOrUp::on_btn_cancel_clicked()
{this->hide();
}

这个Dlg_addOrUp既是添加页面又是修改页面里面m_flag=-1时是添加,非-1时是修改

修改图书

dao层:

//修改图书
void SqlMgr::updateBook(QStringList data){QSqlQuery q(m_db);QString sql=QString("update book set"" name='%1',press='%2',type1='%3',type2='%4',""type3='%5',cnt='%6' where bookid='%7';").arg(data[1]).arg(data[2]).arg(data[4]).arg(data[5]).arg(data[6]).arg(data[3]).arg(data[0]);bool ret=q.exec(sql);//执行查询语句if(ret==false){qDebug()<<q.lastError();}
}

控制层:


void cell_BookMgr::on_btn_bookUpdate_clicked()
{//判断有没有选中一行将要修改的数据//要知道鼠标点中哪一行int r=ui->tableView->currentIndex().row();if(r<0){QMessageBox::information(nullptr,"信息","请选中要更新的一行",QMessageBox::Ok);}else{qDebug()<<"update被调用...";//获得选中的一行的id拿出来auto it= m_model.item(r,0)->text();Dlg_addOrUp dlg;dlg.setFlag(it.toInt());//修改dlg.showDetial(it.toInt());//显示要修改的信息dlg.exec();initPage();}
}

显示到页面上信息(Dlg_addOrUp):

void Dlg_addOrUp::showDetial(int id)
{QString sql=QString("where bookid= %1").arg(id);//先查询信息显示到页面上QVector<QStringList> vec =SqlMgr::getInstance()->getBooks(sql);QStringList data=vec[0];//查出来的是一条数据ui->le_name->setText(data[1]);ui->le_press->setText(data[2]);ui->cb1->setCurrentText(data[3]);ui->cb2->setCurrentText(data[4]);ui->cb3->setCurrentText(data[5]);ui->le_count->setText(data[6]);
}

更新:

void Dlg_addOrUp::addOrUp()
{QStringList strList;//添加if(m_flag==-1){//获取页面输入strList<<ui->le_name->text();strList<<ui->le_press->text();strList<<ui->le_count->text();strList<<ui->cb1->currentText();strList<<ui->cb2->currentText();strList<<ui->cb3->currentText();qDebug()<<"==== "<<strList;//调用数据添加函数SqlMgr::getInstance()->addBooks(strList);}else{//修改strList.clear();strList<<QString::number(m_flag);//把bookid拿进去//获取页面输入strList<<ui->le_name->text();strList<<ui->le_press->text();strList<<ui->le_count->text();strList<<ui->cb1->currentText();strList<<ui->cb2->currentText();strList<<ui->cb3->currentText();SqlMgr::getInstance()->updateBook(strList);}
}

在这里插入图片描述
在这里插入图片描述

删除图书

遇到的错误

在这里插入图片描述

//删除图书
QString SqlMgr:: delBook(QString bookId){QSqlQuery q(m_db);QString sql=QString("delete from book where bookid= %1").arg(bookId);bool ret=q.exec(sql);if(!ret){qDebug()<<q.lastError().text();return "fail";}return "success";
}
void cell_BookMgr::on_btn_bookDel_clicked()
{//获取鼠标点击到哪一行了int r=ui->tableView->currentIndex().row();if(r<0){QMessageBox::information(nullptr,"信息","请选中要删除的一行",QMessageBox::Ok);}else{auto  id =m_model.item(r,0)->text();QString str=SqlMgr::getInstance()->delBook(id);QMessageBox::information(nullptr,"信息",str=="success"?"删除成功":"删除失败",QMessageBox::Ok);initPage();}
}

借阅图书

创建一个窗口类
在这里插入图片描述
Dlg_getsetbook

#include "dlg_getsetbook.h"
#include "ui_dlg_getsetbook.h"
#include"dao/sqlmgr.h"
#include"QMessageBox"
Dlg_getSetBook::Dlg_getSetBook(QWidget *parent) :QDialog(parent),ui(new Ui::Dlg_getSetBook)
{ui->setupUi(this);
}Dlg_getSetBook::~Dlg_getSetBook()
{delete ui;
}void Dlg_getSetBook::showBorrowBook(QString bookName)
{//在页面上显示图书ui->le_bookname->setText(bookName);
}void Dlg_getSetBook::setBookId(QString bookid)
{m_bookid=bookid;
}void Dlg_getSetBook::on_btn_ok_clicked()
{//点击确定之后获取页面上的数据进行调用数据库auto userName=ui->le_username->text();auto pwd=ui->le_pwd->text();//判断用户是否存在bool ret=SqlMgr::getInstance()->login(userName,pwd);if(ret==false){QMessageBox::information(nullptr,"提示","该用户不存在",QMessageBox::Ok);return;}//  图书借阅   QString borrowBook(QString userId,QString bookId);//获取用户idQString userid =  SqlMgr::getInstance()->getUserid(userName,pwd);m_userid=userid;if(m_userid==""&&m_bookid==""){QMessageBox::information(nullptr,"提示","用户id或图书id为null",QMessageBox::Ok);return;}QString str=SqlMgr::getInstance()->borrowBook(m_userid,m_bookid);QMessageBox::information(nullptr,"提示",str=="借阅成功"?"借阅成功":"借阅失败",QMessageBox::Ok);//隐藏窗口this->hide();
}#ifndef DLG_GETSETBOOK_H
#define DLG_GETSETBOOK_H#include <QDialog>namespace Ui {
class Dlg_getSetBook;
}class Dlg_getSetBook : public QDialog
{Q_OBJECTpublic:explicit Dlg_getSetBook(QWidget *parent = nullptr);~Dlg_getSetBook();//显示你借的那一本书void showBorrowBook(QString bookName);void setBookId(QString bookid);private slots:void on_btn_ok_clicked();private:Ui::Dlg_getSetBook *ui;QString m_bookid;QString m_userid;
};#endif // DLG_GETSETBOOK_H

dao:

//图书借阅
QString SqlMgr::borrowBook(QString userId,QString bookId){QSqlQuery q(m_db);QString sql=QString("update book set cnt=cnt-1 where bookid = %1").arg(bookId);bool ret=q.exec(sql);//执行查询语句if(ret==false){qDebug()<<q.lastError().text();return "借阅失败";}//QDateTime::currentSecsSinceEpoch()QString start =secondsToDateString(QDateTime::currentSecsSinceEpoch());QString end =secondsToDateString(QDateTime::currentSecsSinceEpoch()+3600*24*10);sql=QString("insert into record values(null,%1,%2,'%3','%4')").arg(userId).arg(bookId).arg(start).arg(end);ret=q.exec(sql);//执行查询语句if(ret==false){qDebug()<<q.lastError().text();return "借阅失败";}return "借阅成功";}

dao:(getuserid)


QString SqlMgr::getUserid(QString userName, QString pwd)
{QSqlQuery q(m_db);QString sql=QString("select id from user where username = '%1' and password = '%2' ").arg(userName).arg(pwd);bool ret=q.exec(sql);//执行查询语句if(ret==false){qDebug()<<q.lastError().text();return "";}QString userid = "";if (q.next()) { // 移动到结果集中的第一条记录userid = q.value(0).toString();}return userid;
}
QString SqlMgr::secondsToDateString(qint64 seconds)
{QDateTime dateTime = QDateTime::fromSecsSinceEpoch(seconds);QString dateString = dateTime.toString("yyyy-MM-dd");return dateString;
}

控制层:

//借阅图书
void cell_BookMgr::on_btn_BookRecord_clicked()
{//判断点击了哪一行数据int r=ui->tableView->currentIndex().row();if(r<0){QMessageBox::information(nullptr,"信息","请选中要借阅的图书",QMessageBox::Ok);}else{auto bookid =m_model.item(r,0)->text();//获得cnt cnt<=0 库存没了不能借 r行的6列auto cnt =m_model.item(r,6)->text();if(cnt<="0"){QMessageBox::information(nullptr,"信息","该书没有库存了,嗷了个嗷~",QMessageBox::Ok);return;}//否则向下执行 要进行登记是谁借了这本书调用子页面Dlg_getSetBook dlg;//获得书的名字auto bookName =m_model.item(r,1)->text();dlg.setBookId(bookid);//设置图书iddlg.showBorrowBook(bookName);dlg.exec();initPage();}

搜索图书

控制层:(直接调用initPage函数)

void cell_BookMgr::on_le_search_textChanged(const QString &arg1)
{QString sql=QString("where name like '%%1%' or type1 = '%1' or type2 = '%1' or type3 = '%1' ").arg(arg1);initPage(sql);
}

借阅记录管理功能

获取借阅记录

在这里插入图片描述
dao:

//获取借阅记录
QVector <QStringList> SqlMgr::getRecord(QString strCondition){QSqlQuery q(m_db);QString sql=QString("select * from record %1").arg(strCondition);QVector<QStringList> vec;//执行bool ret=q.exec(sql);if(!ret){qDebug()<<q.lastError().text();}else{QStringList strList;//获取这些数据有几列int col=q.record().count();//从q里面获取数据while(q.next()){strList.clear();for(int i=0;i<col;i++){//把这一行数据放进去strList<<q.value(i).toString();}vec.push_back(strList);}}return vec;
}

控制层:

void cell_Record::initPage(QString condition){auto vec=SqlMgr::getInstance()->getRecord(condition);//拿数据显示到页面m_model.clear();//在设置一次头m_model.setHorizontalHeaderLabels(QStringList{"图书id","图书名称","价格","类型1","类型2","类型3","数量","图片"});for(QStringList strList:vec){QList<QStandardItem*> items;for(int i=0;i<strList.size();i++){items.append(new QStandardItem(strList[i]));}m_model.appendRow(items);}}void cell_Record::on_le_search_textChanged(const QString &arg1)
{QString sql=QString("where start like '%%1%' or end like '%%1%' or userid = %1 or bookid = %1").arg(arg1);initPage(sql);
}

模糊查询记录

通过开始时间和结束时间与用户名和密码进行查询

void cell_Record::on_le_search_textChanged(const QString &arg1)
{//同过开始时间和结束时间与用户名和密码进行查询QString sql=QString("where start like '%%1%' or end like '%%1%' or user.username = '%1' or book.name= '%1'").arg(arg1);initPage(sql);
}

归还图书

数据库层:

//归还图书
QString SqlMgr::returnBook(QString userId,QString bookId){//根据userid==bookid删除记录 在根据bookid为本书cnt(库存+1)QSqlQuery q(m_db);
//    qDebug()<<"bookid= "<<bookId<<" userid = "<<userId;/** 假如a(id=1)借西游记(bookid=6) b(id=2)借了西游记(bookid=6)* 登录b还a借的书也是会成功的 b(id=2) a借的书(bookid=6)
*/QString sql=QString("delete from record where userid = %1 and bookid = %2").arg(userId).arg(bookId);bool ret=q.exec(sql);if(ret==false){qDebug()<<q.lastError().text();return "归还失败";}sql=QString("update book set cnt = cnt+1 where bookid = %1").arg(bookId);//    qDebug()<<"bookid= ======"<<bookId;ret=q.exec(sql);if(ret==false){qDebug()<<q.lastError().text();return "归还失败";}return "归还成功";
}

控制层:


//归还图书
void cell_Record::on_btn_return_clicked()
{//获取鼠标点中的哪一行int r=ui->tableView->currentIndex().row();if(r<0){QMessageBox::information(nullptr,"信息","请选中要归还的图书",QMessageBox::Ok);}else{//弹出子页面用户登录之后在删除Dlg_getSetBook dlg;//获得书的名字QString tempBookid=m_model.item(r,2)->text();QString bookName=getBookName(tempBookid.toInt());//获取图书idauto bookid = m_model.item(r,2)->text();//获取useridauto userid = m_model.item(r,1)->text();dlg.setBookId(bookid);dlg.setUserId(userid);dlg.setFlag(true);dlg.showBorrowBook(bookName);//设置到页面上dlg.exec();initPage();}
}QString cell_Record::getBookName(int bookid)
{QString bookName;bookName=SqlMgr::getInstance()->getBookName(bookid);return bookName;
}

Dlg_setgetBook

void Dlg_getSetBook::on_btn_ok_clicked()
{//点击确定之后获取页面上的数据进行调用数据库auto userName=ui->le_username->text();auto pwd=ui->le_pwd->text();//判断用户是否存在bool ret=SqlMgr::getInstance()->login(userName,pwd);if(ret==false){QMessageBox::information(nullptr,"提示","该用户不存在",QMessageBox::Ok);return;}//获取当前登录在Dlg_getsetbook窗口的用户idQString CurUserid =  SqlMgr::getInstance()->getUserid(userName,pwd);if(m_userid==""&&m_bookid==""){QMessageBox::information(nullptr,"提示","用户id或图书id为null",QMessageBox::Ok);return;}if(m_flag==false){//借阅//借阅图书的时候用当前登录的用户的用户id借阅m_userid=CurUserid;QString str=SqlMgr::getInstance()->borrowBook(m_userid,m_bookid);QMessageBox::information(nullptr,"提示",str=="借阅成功"?"借阅成功":"借阅失败",QMessageBox::Ok);}else{//归还if(CurUserid==m_userid){QString str=SqlMgr::getInstance()->returnBook(m_userid,m_bookid);QMessageBox::information(nullptr,"提示",str=="归还成功"?"归还成功":"归还失败",QMessageBox::Ok);}else{QMessageBox::information(nullptr,"提示","用户: "+userName+" 未借此书",QMessageBox::Ok);}}//隐藏窗口this->hide();
}

出现的问题

在这里插入图片描述
改造一下归还函数

//归还图书
QString SqlMgr::returnBook(QString userId,QString bookId,QString recordId){//根据userid==bookid删除记录 在根据bookid为本书cnt(库存+1)QSqlQuery q(m_db);
//    qDebug()<<"bookid= "<<bookId<<" userid = "<<userId;/** 假如a(id=1)借西游记(bookid=6) b(id=2)借了西游记(bookid=6)* 登录b还a借的书也是会成功的 b(id=2) a借的书(bookid=6)
*/QString sql=QString("delete from record where userid = %1 and bookid = %2 and id= %3").arg(userId).arg(bookId).arg(recordId);bool ret=q.exec(sql);if(ret==false){qDebug()<<q.lastError().text();return "归还失败";}sql=QString("update book set cnt = cnt+1 where bookid = %1").arg(bookId);//    qDebug()<<"bookid= ======"<<bookId;ret=q.exec(sql);if(ret==false){qDebug()<<q.lastError().text();return "归还失败";}return "归还成功";
}//转换日期格式
QString SqlMgr::secondsToDateString(qint64 seconds)
{QDateTime dateTime = QDateTime::fromSecsSinceEpoch(seconds);QString dateString = dateTime.toString("yyyy-MM-dd");return dateString;
}QString SqlMgr::getBookName(int bookid)
{QSqlQuery q(m_db);QString sql=QString("select name from book where bookid = %1").arg(bookid);bool ret =q.exec(sql);if(!ret){qDebug()<<q.lastError().text();return "";}QString bookName="";if(q.next()){bookName= q.value(0).toString();return bookName;}return bookName;
}

添加一下这个函数
在这里插入图片描述
在这里插入图片描述

#include "dlg_getsetbook.h"
#include "ui_dlg_getsetbook.h"
#include"dao/sqlmgr.h"
#include"QMessageBox"
Dlg_getSetBook::Dlg_getSetBook(QWidget *parent) :QDialog(parent),ui(new Ui::Dlg_getSetBook)
{ui->setupUi(this);
}Dlg_getSetBook::~Dlg_getSetBook()
{delete ui;
}void Dlg_getSetBook::showBorrowBook(QString bookName)
{//在页面上显示图书ui->le_bookname->setText(bookName);
}void Dlg_getSetBook::setBookId(QString bookid)
{m_bookid=bookid;
}void Dlg_getSetBook::setFlag(bool flag)
{m_flag=flag;
}void Dlg_getSetBook::setUserId(QString userid)
{m_userid=userid;
}void Dlg_getSetBook::setRecordId(QString recordid)
{m_recordid=recordid;
}void Dlg_getSetBook::on_btn_ok_clicked()
{//点击确定之后获取页面上的数据进行调用数据库auto userName=ui->le_username->text();auto pwd=ui->le_pwd->text();//判断用户是否存在bool ret=SqlMgr::getInstance()->login(userName,pwd);if(ret==false){QMessageBox::information(nullptr,"提示","该用户不存在",QMessageBox::Ok);return;}//获取当前登录在Dlg_getsetbook窗口的用户idQString CurUserid =  SqlMgr::getInstance()->getUserid(userName,pwd);if(m_userid==""&&m_bookid==""){QMessageBox::information(nullptr,"提示","用户id或图书id为null",QMessageBox::Ok);return;}if(m_flag==false){//借阅//借阅图书的时候用当前登录的用户的用户id借阅m_userid=CurUserid;QString str=SqlMgr::getInstance()->borrowBook(m_userid,m_bookid);QMessageBox::information(nullptr,"提示",str=="借阅成功"?"借阅成功":"借阅失败",QMessageBox::Ok);}else{//归还if(CurUserid==m_userid){//归还的时候还要用到记录idQString str=SqlMgr::getInstance()->returnBook(m_userid,m_bookid,m_recordid);QMessageBox::information(nullptr,"提示",str=="归还成功"?"归还成功":"归还失败",QMessageBox::Ok);}else{QMessageBox::information(nullptr,"提示","用户: "+userName+" 未借此书",QMessageBox::Ok);}}//隐藏窗口this->hide();
}

清空借阅记录

dao:


void SqlMgr::clearRecord()
{//删除所有图书QSqlQuery q(m_db);QString sql=QString("delete from record;");bool ret=q.exec(sql);//执行查询语句if(ret==false){qDebug()<<q.lastError();return;}sql=QString("delete from sqlite_sequence where name= 'record';");ret=q.exec(sql);//执行查询语句if(ret==false){qDebug()<<q.lastError();return;}qDebug()<<"clearRecord()成功.......";}

控制层:

void cell_Record::on_btn_clear_clicked()
{SqlMgr::getInstance()->clearRecord();initPage();
}

登录功能

控制层:

void Dlg_login::on_btn_login_clicked()
{auto username=ui->username->text();auto pwd=ui->password->text();if(username==""||pwd==""){QMessageBox::information(nullptr,"提示","用户名或密码不能为空",QMessageBox::Ok);return;}bool ret=SqlMgr::getInstance()->login(username,pwd);if(ret){setResult(1);hide();}else{QMessageBox::information(nullptr,"提示","用户名或密码错误",QMessageBox::Ok);}
}

dao:

//返回      true登录成功
bool SqlMgr::login(QString username, QString password)
{QSqlQuery q(m_db);QString sql=QString("select *from user where username='%1' and password='%2'").arg(username).arg(password);bool ret=q.exec(sql);//执行查询语句 执行成功返回trueif(ret==false){qDebug()<<q.lastError().text();}//执行这个q.next()判断是否还有可以执行成功ret=q.next();return ret;
}

在这里插入图片描述

页面展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/72108.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python学习 -- logging模块

logging 模块是 Python 中用于记录日志的标准库&#xff0c;它提供了丰富的功能&#xff0c;可以帮助开发者进行日志记录和管理。以下是关于logging模块的详细使用方式&#xff0c;包括日志级别、处理流程、Logger 类、Handler 类、Filter 类、Formatter 类以及模块中常用函数等…

shell入门运算符操作、条件判断

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xf…

PCIe 5.0验证实战,经常遇到的那些问题?

PCIe 5.0是当前最新的PCI Express规范&#xff0c;提供了更高的数据传输速率和更大的带宽。 PCIe是连接两个芯片的接口&#xff0c;负责两个芯片通信, 连接芯片的通路为高速SerDes, 称之为链路。PCIe确保通路正常-链路训练状态机。PCIe在芯片内部是非常重要的一个大的模块&…

YOLOv5改进算法之添加CA注意力机制模块

目录 1.CA注意力机制 2.YOLOv5添加注意力机制 送书活动 1.CA注意力机制 CA&#xff08;Coordinate Attention&#xff09;注意力机制是一种用于加强深度学习模型对输入数据的空间结构理解的注意力机制。CA 注意力机制的核心思想是引入坐标信息&#xff0c;以便模型可以更好地…

大数据课程K20——Spark的SparkSQL概述

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Spark的SparkSQL由来; ⚪ 了解Spark的SparkSQL特点; ⚪ 了解Spark的SparkSQL优势; ⚪ 掌握Spark的SparkSQL入门; 一、SparkSQL概述 1. 概述 Spark为结构化数据处理引入了一个称…

STM32单片机OLED贪吃蛇游戏记分计时

实践制作DIY- GC00165---OLED贪吃蛇游戏 一、功能说明&#xff1a; 基于STM32单片机设计---OLED贪吃蛇游戏 二、功能说明&#xff1a; STM32F103C系列最小系统板0.96寸OLED显示器上、下、左、右4个按键 1.通过OLED配合按键实现贪吃蛇游戏 2.可以上下左右移动。 3.可以统计显…

golang-bufio 缓冲写

1. 缓冲写 在阅读这篇博客之前&#xff0c;请先阅读上一篇&#xff1a;golang-bufio 缓冲读 // buffered output// Writer implements buffering for an io.Writer object. // If an error occurs writing to a Writer, no more data will be // accepted and all subsequent…

搭建vue3项目并git管理

搭建vue3项目 采用vue3的create-vue脚手架搭建项目&#xff0c;底层是vite&#xff0c;要求环境 node 16.0及以上&#xff08;node -v检查node版本&#xff09; 在文件夹右键->终端-> npm init vuelatest&#xff0c;输入项目名称&#xff0c;根据需要选择是否装包 src…

04 卷积神经网络搭建

一、数据集 MNIST数据集是从NIST的两个手写数字数据集&#xff1a;Special Database 3 和Special Database 1中分别取出部分图像&#xff0c;并经过一些图像处理后得到的[参考]。 MNIST数据集共有70000张图像&#xff0c;其中训练集60000张&#xff0c;测试集10000张。所有图…

deepstream6.2部署yolov5详细教程与代码解读

文章目录 引言一.环境安装1、yolov5环境安装2、deepstream环境安装 二、源码文件说明三.wts与cfg生成1、获得wts与cfg2、修改wts 四.libnvdsinfer_custom_impl_Yolo.so库生成五.修改配置文件六.运行demo 引言 DeepStream 是使用开源 GStreamer 框架构建的优化图形架构&#xf…

cesium创建基本的实体、点、线、多边形(vue)

1.通过viewer实例的entities对象实现 实现代码&#xff1a; <template><div id"container"></div> </template><script> import * as Cesium from cesium/Cesium import "cesium/Widgets/widgets.css" export default {mo…

LeetCode刷题笔记【25】:贪心算法专题-3(K次取反后最大化的数组和、加油站、分发糖果)

文章目录 前置知识1005.K次取反后最大化的数组和题目描述分情况讨论贪心算法 134. 加油站题目描述暴力解法贪心算法 135. 分发糖果题目描述暴力解法贪心算法 总结 前置知识 参考前文 参考文章&#xff1a; LeetCode刷题笔记【23】&#xff1a;贪心算法专题-1&#xff08;分发饼…

gRPC远程进程调用

gRPC远程进程调用 rpc简介golang实现rpc方法一net/rpc库golang实现rpc方法二jsonrpc库grpc和protobuf在一起第一个grpc应用grpc服务的定义和服务的种类grpc stream实例1-服务端单向流grpc stream实例2-客户端单向流grpc stream实例3-双向流grpc整合gin

【2023高教社杯】C题 蔬菜类商品的自动定价与补货决策 问题分析、数学模型及python代码实现

【2023高教社杯】C题 蔬菜类商品的自动定价与补货决策 1 题目 C题蔬菜类商品的自动定价与补货决策 在生鲜商超中&#xff0c;一般蔬菜类商品的保鲜期都比较短&#xff0c;且品相随销售时间的增加而变差&#xff0c; 大部分品种如当日未售出&#xff0c;隔日就无法再售。因此&…

已经2023年了,你还不会手撕轮播图?

目录 一、前言二、动画基础1. 定时器2. left与offsetLeft3. 封装函数3.1 物体3.2 目标点3.3 回调函数 4.封装 三、基础结构3.1 焦点图3.2 按钮3.3 小圆点3.4 总结 四、按钮显示五、圆点5.1 生成5.2 属性5.3 移动 六、按钮6.1 准备6.2 出错6.2.1 小圆点跟随6.2.2 图片返回 6.3 b…

BLE架构与开源协议栈

BLE架构&#xff1a; 简单来说&#xff0c;BLE协议栈可以分成三个部分&#xff0c;主机(host)程序&#xff0c;控制器(controller)程序&#xff0c;主机控制器接口(HCI)。如果再加上底层射频硬件和顶层用户程序&#xff0c;则构成了完整的BLE协议&#xff0c;如下图所示&#…

ModuleNotFoundError: No module named ‘lavis‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

c语言实训心得3篇集合

c语言实训心得体会一&#xff1a; 在这个星期里&#xff0c;我们专业的学生在专业老师的带领下进行了c语言程序实践学习。在这之前&#xff0c;我们已经对c语言这门课程学习了一个学期&#xff0c;对其有了一定的了解&#xff0c;但是也仅仅是停留在了解的范围&#xff0c;对里…

第十八课、Qt 下载、安装与配置

功能描述&#xff1a;介绍了 Qt 的下载、安装和配置的全部过程&#xff0c;并对关键页面选项进行了详细说明 一、Qt 的下载 Qt 官方下载地址&#xff1a;https://www.qt.io/zh-cn/downloadhttps://download.qt.io/https://download.qt.io/https://www.qt.io/zh-cn/download进入…

GptFuck—开源Gpt4分享

这个项目不错&#xff0c;分享给大家 项目地址传送门