Qt+MySQL实现数据库图书管理系统

实验 5 数据库程序设计

一、实验目的 

1、 设计并实现一个精简的图书管理系统,具有入库、查询、借书、还书、借书证管理等基本功能。 

2、 通过本次设计来加深对数据库的了解和使用,同时提高自身的系统编程能力。   

 

二、实验平台 

开发工具:Qt creator 4.0.1(Qt版本:5.6.1 MSVC 2013,32bits)

数据库平台:MySQL5.7

实验平台:Windows10

 

三、总体设计 

1、系统架构描述 

本系统主要包括以下模块/功能:

(1)使用须知

(2)注册

(3)用户登录

(4)管理员登陆

(5)图书查询

(6)借书

(7)还书

(8)显示所有书籍

(9)新书入库

(10)书籍排序

(11)查看借阅情况

(12)查看用户表

(13)删除用户(收回权限)

其中(1)、(2)、(5)属于公用功能,也就是说,任何使用这款软件的人都可以查看使用须知、注册以及查询图书信息;(3)、(6)、(7)为用户设计,只有注册过的用户才能借书、还书。余下的模块/功能为管理员设计,是本系统中最复杂的部分。

需要说明的是,我没有设计管理员注册模块,因为在实际的应用情境中,显然不是随便一个人都能通过注册成为某个系统的管理员,所以,管理员权限由我这个"最高的管理员"直接在数据库中添加,从而防止了使用过程中可能出现的安全问题。

系统处理基本流程如下:

 Qt+MySQL实现数据库图书管理系统

下面用表格的形式对各模块功能说明如下:

使用须知

点击后弹出使用须知。

注册

用于用户注册,供用户输入用户名、密码、并确认密码。只有注册后方可借书。

用户登录

用户登录。

管理员登陆

管理员登陆。

 

图书查询

可在输入栏中输入书籍名称,点击"点我搜索"按钮查询这本书的信息。(如果数据库中有这本书)

借书

用于用户借书。

还书

用于用户还书。

显示所有书籍

进入管理员界面后方可使用,点击显示库存所有书籍。

 

新书入库

进入管理员界面后方可使用,可输入书籍信息,点击"提交书记入库信息"按钮完成新书入库。

 

书籍排序

进入管理员界面后方可使用,点击"书籍排序"按钮按库存量从小到大对书籍排序。方便管理员掌握书记库存情况。

查看借阅情况

进入管理员界面后方可使用,查看用户节约情况。

查看用户表

进入管理员界面后方可使用,查看注册的用户信息。

删除用户

进入管理员界面后方可使用,删除用户。

 

2、数据库表设计

数据库表设计是本次大作业中比较重要的一环,但是这个工作并不复杂。本次作业我新建了一个叫mybms(my book management system)的数据库,并定义了如下表格:

(1)管理员表(manager):

manager_name

password

   

其中manager_name是主键。各个属性从左到右依次表示:管理员名字、管理员密码。

(2)用户表(user):

user_name

password

   

其中user_name是主键。各个属性从左到右依次表示:用户名字、用户密码。

 

(3)书籍信息表(book):

book_id

book_name

author_name

press_name

price

storage

           

其中book_id是主键。各个属性从左到右依次表示:书籍编号、书名、作者名、出版社名、价格和库存量。

 

(4)借阅表(loan):

loan_id

book_id

book_name

user_name

       

其中loan_id是主键,book_id是外键,参照book表。各个属性从左到右依次表示:借阅编号、书籍编号、书名、用户名(即借阅者的名字)。

相关的SQL代码如下:

create database `mybms`;

use `mybms`;

 

create table `manager`(

    `manager_name` varchar(15) primary key,

`password` varchar(20) not null

);

 

create table `user`(

    `user_name` varchar(15) primary key,

`password` varchar(20) not null

);

 

create table `book`(

    `book_id` char(5) primary key,

`book_name` varchar(20) not null,

`author_name` varchar(20),

`press_name` varchar(20),

`price` float,

`storage` int(12)

);

 

create table `loan`(

    `loan_id` char(5) primary key,

`book_id` char(5),

`book_name` varchar(20),

    `user_name` varchar(15),

foreign key(`book_id`) references `book`(`book_id`)

);

 

3、所用开发技术

(1)MySQL

MySQL是一款知名的开源关系型数据库管理系统,这次作业用到的MySQL的知识并不复杂,关键是要想清楚每张表需要什么数据以及每个数据的类型,为了配合Qt的QString类使用,我把大部分的数据都定义成了char。

(2)Qt

Qt本质上是一个C++的框架,用来写图形界面非常方便。使用Qt自己的IDE:QtCreator更加体现了Qt GUI编程的方便性。Qt Creator提供了所谓的"设计模式",在这个模式下程序员可以像画画一样用现成的控件进行布局,本程序的主界面就是用这种方式完成的。

 

四、详细设计

1.界面布局

 

1.1主界面

采用Qt Creator的设计模式布局,在QMainWindow类下包含了:QWidget、QPushButton、QLabel、QTabelView、QLineEdit等控件,其中QWidget是整个窗口,QPushButton是按钮,QLabel是标签,QTabelView是中间的表格,QLineEdit用来输入文字,可以被当成一个输入框。

为了界面的美观,添加了Qt资源文件(背景图)。实现背景效果的方法是:右键单击设计模式界面,选择"改变样式表",在选择资源选项中选中需要添加的图片,这里可以根据需要把图片设置成border-image或者background,我选择的是border-image。之后还有一个很重要的细节是,把当前窗口中的那行代码改成:#centralWidget{border-image: url(:/image/images/bkg_sea.png);}(如下图所示),它表示仅对centralWidget控件进行背景填充,这里的centralWidget是我自己起的名字,其实就是上文的QWidget。如果不这样设定的话,设计模式下的每个控件都会被填充上背景图,看上去非常丑。

Qt+MySQL实现数据库图书管理系统


1.2用户界面

如下图所示,用户登录以后进入用户界面:

(图被CSDN吃了)

界面提示用户使用图书管理系统要遵守的一些规定,在最下方,用户可以输入书名进行借阅或者归还,借阅成功、节约失败、归还成功、归还失败都会有相应的对话框提示。(由于这里是讲界面布局,所以具体功能将留到"3.功能实现"叙述)

实现这个界面的主要代码如下:

//用户界面

voidMainWindow::goto_ufunction_window(boolflag){

if(flag==0)

return;

else{

//必要的初始化

ufunction_window=newQWidget();

ufunction_warning_txtedit=newQTextEdit;

ufunction_borrow_lb=newQLabel;

ufunction_return_lb=newQLabel;

ufunction_borrow_le=newQLineEdit;

ufunction_return_le=newQLineEdit;

ufunction_borrow_btn=newQPushButton(tr("点击借阅"));

ufunction_return_btn=newQPushButton(tr("点击归还"));

ufunction_vblo_main=newQVBoxLayout;

ufunction_hblo_bottom=newQHBoxLayout;

     

//QTextEditQLabel的文字

 

ufunction_window->setWindowTitle(tr("您已进入用户界面"));

ufunction_warning_txtedit->setText(tr("尊敬的用户,为了您和他人的使用方便,请遵守以下规定:"

"\n"

"1、请勿损坏书籍;"

"\n"

"2、请勿逾期不还;"

"\n"

"3、如果违反,管理员有权注销您的借书权限!"));

ufunction_borrow_lb->setText(tr("输入需要借阅的书籍编号:"));

ufunction_return_lb->setText(tr("输入需要归还的书籍编号:"));

 

//布局

ufunction_hblo_bottom->addStretch();

ufunction_hblo_bottom->addWidget(ufunction_borrow_lb);

ufunction_hblo_bottom->addWidget(ufunction_borrow_le);

ufunction_hblo_bottom->addWidget(ufunction_borrow_btn);

ufunction_hblo_bottom->addStretch();

ufunction_hblo_bottom->addWidget(ufunction_return_lb);

ufunction_hblo_bottom->addWidget(ufunction_return_le);

ufunction_hblo_bottom->addWidget(ufunction_return_btn);

ufunction_hblo_bottom->addStretch();

     

//给布局添加控件

ufunction_vblo_main->addWidget(ufunction_warning_txtedit,Qt::AlignHCenter);

ufunction_vblo_main->addLayout(ufunction_hblo_bottom);

 

ufunction_window->setLayout(ufunction_vblo_main);

ufunction_window->resize(800,600);

ufunction_window->show();

 

//连接槽,负责借书、还书

connect(ufunction_borrow_btn,SIGNAL(clicked()),this,SLOT(ufunction_user_borrow()));

connect(ufunction_return_btn,SIGNAL(clicked()),this,SLOT(ufunction_user_return()));

}

}

代码采用水平布局和垂直布局相结合的方式,以垂直布局为主要布局实现了这个界面。最后的两个connect函数连接了控件:ufunction_borrow_btn(借书按钮)、ufunction_return_btn(还书按钮)相应的槽,将界面和功能模块联系了起来。

 

1.3管理员界面

如下图所示:

(图被CSDN吃了)

实现代码:

//管理员界面

voidMainWindow::goto_afunction_window(boolflag){

if(flag==0)

return;

else{

//必要的初始化

afunction_window=newQWidget();

afunction_add_btn=newQPushButton(tr("书籍入库"));//添加书籍

afunction_add_ok_btn=newQPushButton(tr("提交书籍入库信息"));

afunction_delete_btn=newQPushButton(tr("删除用户"));//删除用户

afunction_search_btn=newQPushButton(tr("搜索图书"));//搜索图书

afunction_show_all_btn=newQPushButton(tr("显示库中所有书籍"));//显示所有书籍

afunction_show_order_btn=newQPushButton(tr("按库存量排序(降序)"));

afunction_show_user_btn=newQPushButton(tr("显示用户表"));

afunction_show_loan_btn=newQPushButton(tr("显示借阅表"));

afunction_search_le=newQLineEdit;

afunction_tableview=newQTableView;

afunction_vblo_main=newQVBoxLayout;

afunction_hblo_sub1=newQHBoxLayout;

afunction_hblo_sub2=newQHBoxLayout;

afunction_hblo_sub3=newQHBoxLayout;

afunction_vblo_combine123=newQVBoxLayout;

afunction_window->setWindowTitle(tr("您当前处在管理员界面"));

afunction_tablemodel=newQSqlTableModel(afunction_window);

afunction_tablemodel->setTable("book");

 

//中间表格显示

afunction_tableview->setModel(afunction_tablemodel);

 

//布局添加控件

afunction_vblo_main->addWidget(afunction_tableview);

afunction_hblo_sub1->addWidget(afunction_search_le);

afunction_hblo_sub1->addWidget(afunction_search_btn);

afunction_hblo_sub1->addWidget(afunction_delete_btn);

afunction_hblo_sub2->addWidget(afunction_show_all_btn);

afunction_hblo_sub2->addWidget(afunction_show_order_btn);

afunction_hblo_sub2->addWidget(afunction_add_btn);

afunction_hblo_sub2->addWidget(afunction_add_ok_btn);

afunction_hblo_sub3->addWidget(afunction_show_user_btn);

afunction_hblo_sub3->addWidget(afunction_show_loan_btn);

 

//布局嵌套

afunction_vblo_combine123->addLayout(afunction_hblo_sub1);

afunction_vblo_combine123->addLayout(afunction_hblo_sub2);

afunction_vblo_combine123->addLayout(afunction_hblo_sub3);

afunction_vblo_main->addLayout(afunction_vblo_combine123);

 

//显示

afunction_window->setLayout(afunction_vblo_main);

afunction_window->resize(800,600);

afunction_window->show();

 

//连接槽

connect(afunction_search_btn,SIGNAL(clicked()),this,SLOT(afunction_search()));

connect(afunction_delete_btn,SIGNAL(clicked()),this,SLOT(afunction_delete()));

connect(afunction_show_all_btn,SIGNAL(clicked()),this,SLOT(afunction_show_all()));

connect(afunction_show_order_btn,SIGNAL(clicked()),this,SLOT(afunction_sort()));

connect(afunction_add_btn,SIGNAL(clicked()),this,SLOT(afunction_add()));

connect(afunction_add_ok_btn,SIGNAL(clicked()),this,SLOT(afunction_add_submit()));

connect(afunction_show_user_btn,SIGNAL(clicked()),this,SLOT(afunction_show_user()));

connect(afunction_show_loan_btn,SIGNAL(clicked()),this,SLOT(afunction_show_loan()));

}

}

这个布局相对而言复杂一点,三个水平布局需要加到一个垂直布局,然后再把这个垂直布局加到另一个垂直布局。

 

2.连接数据库

连接数据库部分的代码虽然不多,但是着实折腾了好一阵。

按照常规的做法,需要在Qt的.pro文件中加入代码:QT+= core gui sql,然后将MySQL的libmysql.dll文件放到Qt的工程根目录下,如下图所示:

Qt已经为用户提供了功能强大的数据库相关模块,在完成以上步骤后,将需要用到的模块include进来,如:

#include<QSqlDatabase>

#include<QSqlQuery>

#include<QtSql>

#include<QSqlTableModel>

#include<QSqlRelationalTableModel>

#include<QSqlError>

其中QSqlDatabase、QSqlQuery、QtSql是完成数据库操作所必须的。

之后再定义连接数据库的函数:

boolMainWindow::createConnection(){

//连接MySQL数据库

db=QSqlDatabase::addDatabase("QMYSQL");

//设置主机名

db.setHostName("localhost");

//设置数据库名

db.setDatabaseName("mybms");

//设置账号名

db.setUserName("xxx");

//设置密码名

db.setPassword("csdbs");

//设置端口

db.setPort(3306);

if(!db.open()){

QMessageBox::critical(0,QObject::tr("error"),db.lastError().text());

returnfalse;

}

}

这个函数需要在MainWindow的构造函数里调用。

当然,最后也要考虑到断开数据库连接的问题,只需要在MainWindow的析构函数里调用:db.removeDatabase("mybms");就可以了。此处的db是自己起的变量名,本质上是一个QSqlDatabase对象,"mybms"是数据库的名字。removeDatabase函数是Qt自己提供的,不需要用户自己实现。

但是,按如上步骤做遇到了问题,发现数据库连接不上,经过查阅资料后发现原来是32位的Qt与64位的MySQL不兼容。解决的方法是:在Qt官网上下载名为mysql-connector-c-6.1.9-win32的补丁,将它解压之后,在对应的文件夹下找到libmysql.dll文件,然后将这个文件放进Qt工程根目录就可以了。(这里有两个libmysql.dll,需要用connector生成的那个)

 

3.功能实现

为了方便演示,先在MySQL Workbench中输入如下SQL代码:


insert into `manager` values('manager01','123456');

insert into `user` values('user01','123456');

insert into `book` values

('01','C++程序设计','孟宪福','清华大学出版社',28.00,5),

('02','C++ Primer','Stanley B.Lippman','人民邮电出版社',99.00,5),

('03','浮士德','歌德','人民文学出版社','65.00',4),

('04','简明法语教程','孙辉','外研社','28.80',5),

('05','Linear Algebra','Gilbert Strang','高等教育出版社',32.50,6);

 

通过以上代码,我添加了一个叫manager01的管理员,密码是123456,一个叫user01的用户,密码是123456,我插入了5本书,它们的详细信息如上。下面在这些信息的基础上说明具体的功能实现:

3.1图书查询

在初始界面的输入栏中输入想要查找的书,比如:C++ Primer,点击"点我搜索",就可以查询到这本书的信息。当然,查询成功的前提是数据库中要有这本书,如果没有这本书,搜索结果将不予显示。

主要的实现代码:

voidMainWindow::on_query_btn_clicked(){

QStringbook_name=ui->name_lineEdit->text();

model->setFilter(QString("book_name='%1'").arg(book_name));

model->select();

}

Qt的QTableView模块使得查询变得非常方便。使用setFilter函数、select函数和使用SQL的select...from...where...语句是等价的。同时还有一个便利是这样做可以不用区分大小写,也就是说不管是输入C++ Primer还是c++ PriMeR......都能够查找到结果,这和设计的预期比较一致。

 

3.2使用须知

主要的实现代码:

//使用须知的槽

voidMainWindow::on_notice_btn_clicked(){

notice_window=newQWidget();

notice_vblo=newQVBoxLayout;

notice_head=newQLabel;

notice_line1=newQLabel;

notice_line2=newQLabel;

notice_line3=newQLabel;

notice_line4=newQLabel;

notice_line5=newQLabel;

notice_line6=newQLabel;

notice_head->setText(tr("尊敬的用户,欢迎您使用图书管理系统,以下是使用须知:\n"));

QFontfont_head("MicrosoftYaHei",15,75);

notice_head->setFont(font_head);

notice_line1->setText(tr("1.。。。\n"));

QFontfont1(0,15,0);

notice_line1->setFont(font1);

notice_line2->setText(tr("2.。。。\n"));

QFontfont2(0,15,0);

notice_line2->setFont(font2);

notice_line3->setText(tr("3.。。。\n"));

QFontfont3(0,15,0);

notice_line3->setFont(font3);

notice_line4->setText(tr("4.。。。\n"));

QFontfont4(0,15,0);

notice_line4->setFont(font4);

notice_line5->setText(tr("5.。。。\n"));

QFontfont5(0,15,0);

notice_line5->setFont(font5);

notice_line6->setText(tr("6.如有任何问题,请联系:xxx\n"));

QFontfont6(0,15,0);

notice_line6->setFont(font6);

 

//给布局添加控件

notice_vblo->addWidget(notice_head);

notice_vblo->addWidget(notice_line1);

notice_vblo->addWidget(notice_line2);

notice_vblo->addWidget(notice_line3);

notice_vblo->addWidget(notice_line4);

notice_vblo->addWidget(notice_line5);

notice_vblo->addWidget(notice_line6);

 

//显示

notice_window->setLayout(notice_vblo);

notice_window->resize(800,600);

notice_window->show();

}

 

3.3用户注册

点击用户注册按钮进行用户注册将会出现如下对话框:

(图被CSDN吃了)

用户可以设置自己的用户名和密码,密码需要二次输入以便确认。如果填写的信息不完整,比如,有一个用户只填写了用户名:excited!而没有填写密码,如下图:

(图被CSDN吃了)

那么这样搞肯定是不行的,程序将给出警告:

(图被CSDN吃了)

如果用户输入的密码不一致,比如:

(图被CSDN吃了)

将给出警告:

(图被CSDN吃了)

而如果信息填完整了,密码两次输入也没有问题,但是这个名字已经被注册了,显然也不行,将给出警告:

(图被CSDN吃了)

如果注册成功,将给出提示:

(图被CSDN吃了)

主要的实现代码:

voidMainWindow::user_register(){

//检测用户是否输入了全部的信息

if(register_name_le->text().isEmpty()||register_pwd_le->text().isEmpty()

||register_pwd_check_le->text().isEmpty()){

QMessageBox::critical(NULL,"Error",tr("您填写的信息不完整"),QMessageBox::Yes);

return;

}

//检测密码是否一致

if(register_pwd_le->text().compare(register_pwd_check_le->text())!=0){

QMessageBox::critical(NULL,"Error",tr("两次密码输入不一致!"),QMessageBox::Yes);

return;

}

//查询用户名是否已存在于数据库

QSqlQueryquery;

query.exec("selectuser_namefromuserwhereuser_name='"+register_name_le->text()+"'");

if(query.next()){

QMessageBox::critical(NULL,"Error",tr("该用户名已被注册"),QMessageBox::Yes);

return;

}

//user表中插入用户信息

query.exec("insertintouservalues('"+register_name_le->text()+"','"+register_pwd_check_le->text()+"')");

if(query.isActive()){

QMessageBox::about(0,"mybms",tr("注册成功!"));

register_window->close();//注册成功之后将注册窗口关闭

}

else{

QMessageBox::critical(NULL,"Error",tr("注册失败"),QMessageBox::Yes);

return;

}

}

 

3.4用户登录

用户通过用户登录进入用户功能界面,用户登录界面如下:

(图被CSDN吃了)

如果登陆成功或者失败,同样会有和上面类似的警告或者提示,这里就不重复贴图了。

主要的实现代码:

voidMainWindow::user_login(){

booluser_login_success_flag=0;//一开始设为零表示登录不成功

QSqlQueryquery;

 

//根据用户输入的用户名,在user表中查询其密码

query.exec("selectpasswordfromuserwhereuser_name='"+ulogin_name_le->text()+"'");

if(!query.isActive()){

return;

}

 

//判断密码是否与结果一致

if(query.next()){

QStringuser_pwd=query.value(0).toString();

if(QString::compare(user_pwd,ulogin_pwd_le->text())==0){

user_login_success_flag=1;

ulogin_window->close();

}

else{

QMessageBox::critical(NULL,"Error","密码错误",QMessageBox::Yes);

return;

}

}

//如果数据库中没有此用户名,给出警告

else{

QMessageBox::critical(NULL,"Error","该用户名不存在",QMessageBox::Yes);

return;

}

goto_ufunction_window(user_login_success_flag);//去到用户界面

}

 

3.5借书

借书的界面如下:

(图被CSDN吃了)

用户可以输入书籍的编号进行借书,这个编号可以在一开始的主界面查询比如输入05,对应的书是Linear Algebra,如果借阅成功会显示:

(图被CSDN吃了)

否则显示:

(图被CSDN吃了)

如果同一个用户对一本书进行多次借阅,则会给出警告:

(图被CSDN吃了)

这样就避免了某些用户重复借阅给他人带来不便。

借书本质上是对数据库中的book表做一个查询,如果能找到用户需要的书,就把这条记录插入loan表,同时更新book表的信息。

主要的实现代码:

//借书

voidMainWindow::ufunction_user_borrow(){

//先检查这本书有没有被当前用户借过

QSqlQuerycheck_query;

check_query.exec("selectbook_id,user_namefromloanwherebook_id='"+ufunction_borrow_le->text()+"'");

if(check_query.next()){

QStringcheck_name=check_query.value(1).toString();

if(check_name==ulogin_name_le->text()){

QMessageBox::critical(NULL,"Error",tr("每本书只能借一次!"),QMessageBox::Yes);

return;

}

}

QSqlQueryquery;

boolfind_ok_flag=0;

query.exec("selectbook_id,book_namefrombookwherebook_id='"+ufunction_borrow_le->text()+"'");

if(!query.isActive()){

return;

}

if(query.next()){

QStringbook_id=query.value(0).toString();

QStringbook_name=query.value(1).toString();

if(QString::compare(book_id,ufunction_borrow_le->text())==0){

find_ok_flag=1;

query.exec("updatebooksetstorage=storage-1wherebook_id='"+ufunction_borrow_le->text()+"'");

 

user_borrow_id_int++;

user_borrow_id=QString::number(user_borrow_id_int,10);

 

query.exec("insertintoloanvalues('"+user_borrow_id+"','"+book_id+"','"+book_name+"','"+ulogin_name_le->text()+"')");

QMessageBox::about(0,tr("数据库反馈"),tr("借书成功!"));

}

}

else{

QMessageBox::critical(NULL,"Error","借阅失败,请检查您的拼写!",QMessageBox::Yes);

}

}

 

3.6还书

还书与借书类似,同样需要输入书籍编号,再点击"点击归还",归还成功会提示:

(图被CSDN吃了)

还书其实是在操作loan表和book表,loan表中book_id与用户输入相同的记录需要被delete掉,同时book表中相同book_id的书籍信息也需要更新。

主要的实现代码:

//还书

voidMainWindow::ufunction_user_return(){

QSqlQueryquery;

boolreturn_ok_flag=0;

query.exec("selectloan_id,book_idfromloanwherebook_id='"+ufunction_return_le->text()+"'");

if(!query.isActive()){

return;

}

if(query.next()){

QStringloan_id=query.value(0).toString();

QStringbook_id=query.value(1).toString();

if(QString::compare(book_id,ufunction_return_le->text())==0){

return_ok_flag=1;

query.exec("updatebooksetstorage=storage+1wherebook_id='"+ufunction_return_le->text()+"'");

query.exec("deletefromloanwhereloan_id='"+loan_id+"'");

QMessageBox::about(0,tr("数据库反馈"),tr("归还成功,感谢您的使用!"));

}

}

else{

QMessageBox::critical(NULL,"Error","归还失败,请检查您的拼写!",QMessageBox::Yes);

}

}

 

3.7管理员登陆

管理员登陆界面如下,和用户登录界面类似:

(图被CSDN吃了)

登陆成功、登录失败都会有相应的提示,效果和前面展示的类似,这里从略。

主要的实现代码:

voidMainWindow::admin_login(){

booladmin_login_success_flag=0;

QSqlQueryquery;

//根据用户输入的用户名,在manager表中查询其密码

query.exec("selectpasswordfrommanagerwheremanager_name='"+alogin_name_le->text()+"'");

if(!query.isActive()){

return;

}

//判断密码是否与结果一致

if(query.next()){

QStringadmin_pwd=query.value(0).toString();

if(QString::compare(admin_pwd,alogin_pwd_le->text())==0){

admin_login_success_flag=1;

alogin_window->close();

}

else{

QMessageBox::critical(NULL,"Error","密码错误",QMessageBox::Yes);

return;

}

}

//如果数据库中没有此用户名,给出警告

else{

QMessageBox::critical(NULL,"Error","该管理员不存在",QMessageBox::Yes);

return;

}

goto_afunction_window(admin_login_success_flag);//去到管理员界面

}

 

3.8显示所有书籍

如下图所示,点击"显示库中所有书籍"可以看到当前数据库中所有的书。

(图被CSDN吃了)

主要的实现代码:

//显示所有图书

voidMainWindow::afunction_show_all(){

afunction_tablemodel->setTable("book");

afunction_tablemodel->select();

}

 

3.9书籍排序

为了方便管理员了解每本书的库存量,加入了书籍排序功能。点击"按库存量排序(降序)",将会得到如下图所示的结果,可以看到此时数据库中的书籍都按照storage的大小从小到大排好序了:

(图被CSDN吃了)

这主要是为了方便管理员添加书籍,避免出现storage不够的情况。

主要的实现代码:

//排序

voidMainWindow::afunction_sort(){

afunction_tablemodel->setSort(5,Qt::AscendingOrder);

afunction_tablemodel->select();

}

代码中的参数5表示排序的对象是第5列,第二个参数指定了排序方式:ascending。

 

3.10新书入库

管理员不需要直接操作数据库,仅仅通过这个程序就可以添加书籍信息,这本质上是在对数据库的book表做insert操作。

当处在显示书籍的界面时,点击"书籍入库",会在表上增加一行,管理员可以在这一行里输入新书的信息。比如现在需要添加一本叫做《C++:从入门到放弃》的书,效果如下图所示:

(图被CSDN吃了)

编辑过程中,如果没有点击"提交书籍入库信息",则在这一行的前面会一直有一个*号表示当前处在编辑的状态,确定无误后,即可点击"提交书籍入库信息"进行提交,这样就可以完成书籍入库了。

点击书籍入库按钮后也可以对原来的书籍信息进行修改,但是只要不提交,数据库都不会接收到这个变化。

主要的实现代码:

//添加书籍

voidMainWindow::afunction_add(){

introw_num=afunction_tablemodel->rowCount();

QStringbook_id;

afunction_tablemodel->insertRow(row_num);

afunction_tablemodel->setData(afunction_tablemodel->index(row_num,0),book_id);

//afunction_tablemodel->submitAll();

}

 

//提交添加书籍的修改

voidMainWindow::afunction_add_submit(){

afunction_tablemodel->database().transaction();

if(afunction_tablemodel->submitAll()){

if(afunction_tablemodel->database().commit())

QMessageBox::information(this,tr("数据库反馈"),tr("书籍入库成功!"));

}

else{

afunction_tablemodel->database().rollback();

QMessageBox::warning(this,tr("数据库反馈"),

tr("发生错误:%1").arg(afunction_tablemodel->lastError().text()),

QMessageBox::Ok);

}

}

 

3.11查看借阅情况

管理员可以查看书籍的借阅情况,其实就是访问之前定义过的loan表。在管理员功能界面点击"显示借阅表"即可看到当前的loan_id、book_id、book_name、user_name等信息,如下图所示:

(图被CSDN吃了)

主要的实现代码:

//显示loan

voidMainWindow::afunction_show_loan(){

afunction_tablemodel->setTable("loan");

afunction_tablemodel->select();

}

 

3.12管理用户(查看、删除)

管理员可以对用户进行管理,包括查看用户信息(用户名和密码),以及取消某些不守规矩的用户的借阅权限,也就是把用户从user表给删掉。

例如在当前的界面下选中user02这一行,然后点击"删除用户"按钮,将会弹出警告对话框,如下图所示:

(图被CSDN吃了)

主要的实现代码:

//删除

voidMainWindow::afunction_delete(){

intcur_row=afunction_tableview->currentIndex().row();

intok=QMessageBox::warning(this,tr("删除这个用户"),tr("您确定删除当前行吗?"),

QMessageBox::Yes,QMessageBox::No);

if(ok==QMessageBox::Yes){

afunction_tablemodel->removeRow(cur_row);

afunction_tablemodel->submitAll();

}

else

return;

}

currentIndex函数获取了当前行,removeRow函数可以将某行记录删掉,数据库信息被修改后需要调用submitAll函数提交,只有执行了这个函数才会真的影响到外部连接的MySQL数据库,否则删除无效。

 

五、实验心得

。。。