时间:2021-07-01 10:21:17 帮助过:16人阅读
属性 |
主码/外码 |
数据类型 |
说明 |
Username |
主码 |
varchar(20) |
用户名 |
Password |
|
varchar(20) not null |
密码 |
用户(user)
属性 |
主码/外码 |
数据类型 |
说明 |
Username |
主码 |
varchar(20) |
用户名 |
Password |
|
varchar(20) not null |
密码 |
图书(book)
属性 |
主码/外码 |
数据类型 |
说明 |
book_id |
主码 |
char(5) |
编号 |
Name |
|
varchar(20) not null |
书名 |
Price |
|
float(9,2) |
价格 |
Number |
|
int unsigned |
数量 |
storage_date |
|
date |
入库时间 |
manage_name |
外码,参照manager |
varchar(20) |
入库人员 |
Publisher |
|
varchar(15) not null |
出版社 |
publish_year |
|
year |
出版日期 |
Type |
|
varchar(10) not null |
分类 |
作者信息(book_author)
属性 |
主码/外码 |
数据类型 |
说明 |
Book_id |
主码 外码,参照book |
char(5) |
编号 |
Author_name |
主码 |
varchar(20) |
作者 |
借阅(loan)
属性 |
主码/外码 |
数据类型 |
说明 |
Username |
主码 |
varchar(20) |
用户名 |
book_id |
主码 |
char(5) |
编号 |
loan_number |
主码 |
int unsigned |
单册编号 |
loan_date |
|
date |
借阅日期 |
三.开发技术
本次图书管理系统用MySql和qt进行开发。两者都是知名的跨平台、开源的项目。
mysql被广泛应用于web开发中,相比起其他数据库,其体积较小,而且被多种语言支持,是非常流行的开源关系型数据库。
qt是基于C++的图形界面开发库,它提供了基本窗口控件对象绘制、网络、多线程开发、数据库连接、XML使用等功能。
基于mysql开发的qt应用程序的搭建非常简单,只需安装32位的mysql和qt creator,然后把mysql提供的libmysql.dll放到qt的bin下,而不需要安装特别的插件,因为qt已经默认安装了mysql的驱动。
对于mysql,qt提供了两种驱动,一种是QMYSQL驱动程序,另一种是QODBC驱动程序,在这里我们选择了前者。
qt的数据库驱动程序
qt提供了两种操纵数据库的方式,一种是使用QSqlQuery类,就可以直接使用底层的SQL语句,另一种是使用QsqlTableModel,使用者不需要了解SQL语法,qt对sql语句进行了很好的封装,在这里我们选择了QSqlQuery。
四.详细设计
1.图书搜索
只提供图书检索功能,游客可以选择注册,但是借书权限需要管理员添加。
图书检索实例:
检索采用了‘%string%’形式,可以搜索到包含用户输入字符串的信息。
用户可以不用填写所有信息,只需填写一部分感兴趣的信息即可。代码会根据用户的输入生成相应的SQL查询代码。
为了便于编程,搜索采取的是所有信息的交集,如果想要检索并集,只能分别查询。这样的设计已经基本能够满足用户的搜索需求了。
左侧的类型和右侧的搜索栏是独立的,它们点击后的搜索是单独进行的,而不是取交集。
该系统会对用户输入的语句进行简单的判断,在一些异常情况下,会给出一些提示:
如果是错误的输入,会有sql底层的警告信息:
如果没有查找到结果,也会给出提示。
注:因为没有写预备语句,查询不能保证安全性,对于有意的破坏性语句(sql注入),可能会导致数据库的崩溃。
2.用户注册
注册过程中也会对用户输入的信息做出相应的判断:
注册完成后,会向user表中插入user信息,借书权限默认为false。
3.用户/管理员登录
登录时,会根据用户输入的用户名,在数据库在搜索密码,如果没有搜到,提示用户名不存在,如果搜到的密码和用户输入不匹配,提示密码错误。
切换用户和管理员登录,只需在上面的分栏选择。
游客身份,显示图书搜索界面
用户身份,显示图书搜索、借阅情况界面
管理员身份,显示图书搜索、用户管理、单册入库、多册入库界面
4.借阅情况
在借阅情况窗口,用户可以查到自己的借阅信息,包括书本编号、名称,以及借阅、归还日期。单册编号是为了维护借阅关系的主码,针对一本书被借多次的情况设置的。
同时,用户可在这里进行归还书籍操作。
点击归还后,借阅信息动态更新。同时可以发现,在用户登录后,查询书籍的界面多了一个借阅书籍的按钮,用户可以在查询的过程中进行书本借阅操作,如:
借阅成功后,库存量会减少,然后用户借阅窗口的信息也会动态更新。
如果用户没有选中书籍,或者用户借阅数量已经达到上限,都会给出警告:
5.用户管理
以管理员身份登录后,可以对用户进行管理,在这里可以看到用户的几乎所有信息。同时也可以执行删除/授予借书权限、用户删除操作。
判断是删除还是授予权限,是由用户当前的状态决定。
如果一个用户有未归还的书籍,管理系统会禁止删除操作:
6.单册入库
信息必须全部填写,否则不允许插入:
只有全部填写才能插入书籍:
在插入的同时,会给书籍设置一个编号,编号通过如下算法得到:
id = select count(*)from book
while(exist id) id++
之所以执行第二步,是因为数据库可能因为删除书籍操作导致中间部分编号的缺失。
同时,还会存入当前的入库人员(管理员),入库时间等信息。入库时间是通过获取系统时间得到的,如果计算机的系统时间被篡改了,我们也没有很好的办法。
插入成功后,输入框会自动清空,便于下一次入库。
很遗憾的是,这里并没有对输入数据进行类型检查(预处理操作),所以输入了什么错误的东西,数据库也会一并接收。
删除书籍只提供了指定书的编号删除的功能。因为删除书时一般都有明确的导向,不像查询书籍,需要实现复合条件搜索功能。
7.多册入库
除了单册入库,我们还提供了多册入库的功能,包括了表格的填写,和文本文件的读入:
表格填写入库。
直接点击表格,就可以对内容进行编辑。
如果管理员插入了和原来相同的书籍,我们会询问管理员是否需要合并,如果点击确认,就将原来书籍的数量更新,否则将取消入库。
表格插入也会检测用户输入是否完整的数据,最后是一条条插入数据的。如果哪一条插入失败,会有单独的提示。
同样,我们可以通过文件读入来批量录入,点击右上角的加载文件,文件需要按照一定的格式书写,并且只支持.txt后缀的文件。
以下是一个预先准备好的文件:
读入后的显示效果如下:
此时文件还没有加载到数据库里,需要点击提交表单。
由于这里限定一页只显示13列,而文本有时会有超过13条书本信息的记录,所以点击了提交后,只提交13本书的信息,剩下的书本记录会在提交后继续加载到表格中。
也就是说,对于多条数据,管理员需要多次提交表单。
mysql建立数据库代码:
CREATE SCHEMA `book_manage` ; use book_manage; set autocommit=0; create table `manager` ( `username` varchar(20), `password` varchar(20) not null, primary key(`username`) ); create table `user` ( `username` varchar(20) not null, `password` varchar(20) not null, primary key (`username`) ); create table `book` ( `book_id` char(5), `name` varchar(20) not null, `price` float(9,2) unsigned, `number` int unsigned not null, `storage_date` date, `manage_name` char(20), `publisher` varchar(15) not null, `publish_year` year, `type` varchar(10) not null, primary key(`book_id`), foreign key(`manage_name`) references `manager`(`username`) ); create table `book_author` ( `book_id` char(5), `author_name` varchar(20), primary key(`author_name`,`book_id`), foreign key(`book_id`) references `book`(`book_id`) on delete cascade on update cascade ); create table `loan` ( `username` char(20), `book_id` char(5), `loan_date` date, `loan_number` int unsigned, primary key(`username`,`book_id`,`loan_number`), foreign key(`username`) references `user`(`username`), foreign key(`book_id`) references `book`(`book_id`) );
database.pro
#------------------------------------------------- # # Project created by QtCreator 2016-04-03T16:38:55 # #------------------------------------------------- QT += core gui sql greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = Database TEMPLATE = app QTPLUGIN += QSQLMYSQL SOURCES += main.cpp database.cpp HEADERS += database.h INCLUDEPATH += "C:/Program Files (x86)/MySQL/MySQL Server 5.7/include" LIBS += "C:/Program Files (x86)/MySQL/MySQL Server 5.7/lib/libmysql.lib"
database.h
#ifndef DATABASE_H #define DATABASE_H #include <QObject> #include <QSqlDatabase> #include <QSqlQuery> #include <QVector> class QWidget; class QLineEdit; class QComboBox; class QPushButton; class QLabel; class QGridLayout; class QTabWidget; class QVBoxLayout; class QHBoxLayout; class QTreeWidget; class QTreeWidgetItem; class QGroupBox; class QToolButton; class QTableWidget; class QCheckBox; class QTableWidgetItem; class QTimer; class database : public QObject { Q_OBJECT private: enum{MANAGER,USER,VISITOR,USER_LOGIN,USER_REGISTER}; QString current_user; int user_type; int current_page; int max_page; int user_current_page; int user_max_page; int user_num; int current_row_number; QTimer *timer; QTableWidget *tablewidget; QGridLayout *gridLayout ; QVBoxLayout *vboxLayout0; QVBoxLayout *vboxLayout1; QVBoxLayout *vboxLayout ; QWidget *titleImage; QVBoxLayout *vboxLayout3; QVBoxLayout *vboxLayout2; QHBoxLayout *hboxLayout1; QHBoxLayout *hboxLayout ; QHBoxLayout *hboxLayout2; QHBoxLayout *hboxLayout3; QLabel *spacelabel2; QLabel *spacelabel3; QGroupBox *groupbox; QGroupBox *groupbox1; QPushButton *clearbutton; QPushButton *searchbutton; QPushButton *registerbutton; QPushButton *loginbutton; QPushButton *quitloginbutton; QLabel *label; QTreeWidget *tree; QTreeWidgetItem *root; QLineEdit *nameLine; QLineEdit *publishLine; QLineEdit *priceLine; QLineEdit *priceLine1; QLineEdit *authorLine; QComboBox *dateBox; QComboBox *dateBox1; QComboBox *isLent; QWidget *window; QPushButton *nextbutton; QPushButton *lastbutton; QSqlDatabase db; QSqlQuery query; QTabWidget *mainTabWidget; QTabWidget *loginTabWidget; QWidget *user_loginWidget; QWidget *manager_loginWidget; QLineEdit *username1; QLineEdit *password1; QLineEdit *username2; QLineEdit *password2; QPushButton *okbutton; QVBoxLayout *vboxLayout4; QVBoxLayout *vboxLayout5; QVBoxLayout *vboxLayout6; QHBoxLayout *hboxLayout4; QHBoxLayout *hboxLayout5; QHBoxLayout *hboxLayout6; QGridLayout *gridLayout2; QTabWidget *manageTabWidget; QWidget *addBookWidget; QLabel *label2; QLineEdit *nameLine2; QComboBox *typeBox2; QLineEdit *priceLine2; QLineEdit *authorLine2; QLineEdit *numLine2; QLineEdit *publishLine2; QComboBox *dateBox2; QWidget *window1; QWidget *window2; QWidget *window3; QWidget *window4; QWidget *window5; QWidget *registerWindow; QLabel *label3; QLineEdit *nameLine3; QLineEdit *passwordLine1; QLineEdit *passwordLine2; QPushButton *registerOkButton; QHBoxLayout *hboxLayout7; QHBoxLayout *hboxLayout8; QVBoxLayout *vboxLayout7; QGridLayout *gridLayout3; QLabel *label4; QVector<QString>result; QLabel *label5; QLineEdit *idLine; QVBoxLayout *vboxLayout9; QHBoxLayout *hboxLayout9; QWidget *deletebookWidget; QPushButton *deleteOkButton; QTableWidget *tablewidget1; QVBoxLayout *vboxLayout10; QHBoxLayout *hboxLayout10; QPushButton *deleteUserButton; QPushButton *grantLentButton; QPushButton *lastPageButton; QPushButton *nextPageButton; QTableWidgetItem *item0[13]; QTableWidgetItem *item1[13]; QVector<QString*>userMessage; QTableWidgetItem *item2[10]; QTableWidgetItem *item3[10]; QPushButton *lendBookButton; QTableWidget *tablewidget2; QVector<QString*>loanMessage; QHBoxLayout *hboxLayout11; QVBoxLayout *vboxLayout11; QTableWidgetItem *item4[3]; QPushButton *returnBookButton; QTableWidget *tablewidget3; QVBoxLayout *vboxLayout12; QHBoxLayout *hboxLayout12; QPushButton *addBookOkButton; QPushButton *addBookClearButton; QComboBox *bookType[13]; QComboBox *publishDate[13]; QString bookMessage[7]; QLabel *tipLabel; QWidget *fileWindow; QHBoxLayout *hboxLayout13; QPushButton *loadFileButton; QVector<QString*>multiBookMessage; void setLayout(); bool createConnection(); void setWindowShowBook(int type); void setWindowSearchBook(int type); void setWindowAddBook(); void setWindowUserManage(); void setWindowLoanBook(); void setWindowMutiAddBook(); void setWindowTitle(); void updateManageWindow(); void updateShowBookWindow(); void updateLoanBookWindow(); void updateTitle(int type); bool addBook(); void loadUserMessage(); void loadLoanMessage(); QWidget* createLoginWindow(int type); public: database(QObject *parent = 0); ~database(); private slots: void searchBook(); void updateTime(); void clear(); void quitLogin(); void returnBook(); void managerLogin(); void deleteLogin(); void bookLastPage(); void bookNextPage(); void deleteBook(); void searchBookByType(QTreeWidgetItem*,int); void userLogin(); void setWindowRegister(); void setWindowLogin(); void Register(); void deleteUser(); void grantLent(); void userNextPage(); void userLastPage(); void lendBook(); void oneAddBook(); void mutiAddBook(); void clearAddBookMessage(); void openFile(); }; #endif // DATABASE_H
/* _______________________ | | | author:fish1996 | | start:2016/04/03 | | finish:2016/04/22 | | tool:mysql+qtCreator | | 图书管理系统 | | | ——————————————————————— */ #include "database.h" #include <QWidget> #include <QLineEdit> #include <QLayout> #include <QComboBox> #include <QLabel> #include <QFrame> #include <QGroupBox> #include <QPushButton> #include <QTabWidget> #include <QTreeWidget> #include <QPalette> #include <QBrush> #include <QPixmap> #include <QDateTime> #include <QtSql> #include <QStringList> #include <QPluginLoader> #include <QMessageBox> #include <QCheckBox> #include <QTableWidget> #include <QTimer> #include <QDir> #include <QFileDialog> /* 构造函数 */ database::database(QObject *parent) : QObject(parent) { //初始化变量 user_num = 0; user_type = VISITOR; current_user = "游客"; //新建计时器 timer = new QTimer(); connect(timer, SIGNAL(timeout()), this, SLOT(updateTime())); timer->start(1000); //初始化指针 tablewidget = NULL; tablewidget2 = NULL; nextbutton = NULL; lastbutton = NULL; hboxLayout6 = NULL; lastbutton = NULL; nextbutton = NULL; deleteUserButton = NULL; grantLentButton = NULL; lendBookButton = NULL; returnBookButton = NULL; window4 = NULL; for(int i=0;i<10;i++){ item2[i] = NULL; item3[i] = NULL; } //窗口布局 setLayout(); //连接数据库 if(!createConnection()){ QMessageBox::critical(0,"error","数据库连接失败"); } } /* 析构函数 */ database::~database() { //取消与数据库的连接 db.removeDatabase("book_manage"); } /* _______________________ | | | 第一部分:页面布局 | | | ——————————————————————— */ /* 初始化布局 */ void database::setLayout() { //显示标题栏 setWindowTitle(); //以游客身份新建搜索窗口 setWindowSearchBook(VISITOR); } /* 标题窗口布局*/ void database::setWindowTitle() { //申请内存 QPalette palette; loginbutton = new QPushButton(tr("登录")); registerbutton = new QPushButton(tr("注册")); spacelabel2 = new QLabel(); spacelabel3 = new QLabel("\n\n"); vboxLayout0 = new QVBoxLayout(); hboxLayout2 = new QHBoxLayout(); hboxLayout3 = new QHBoxLayout(); titleImage = new QWidget(); window = new QWidget(); vboxLayout3 = new QVBoxLayout(); mainTabWidget = new QTabWidget(); //登录注册按钮状态设置 registerbutton->setFlat(true); registerbutton->setFixedSize(QSize(60,30)); loginbutton->setFlat(true); loginbutton->setFixedSize(QSize(60,30)); //建立信号与槽 connect(registerbutton,SIGNAL(clicked()),this,SLOT(setWindowRegister())); //点击注册按钮,显示注册窗口 connect(loginbutton,SIGNAL(clicked()),this,SLOT(setWindowLogin())); //点击登录按钮,显示登录窗口 //设置标题图片 QDir d; titleImage->setAutoFillBackground(true); palette.setBrush(QPalette::Background,QBrush(QPixmap(d.currentPath()+"/title.jpg"))); titleImage->setPalette(palette); titleImage->setLayout(hboxLayout2); //标题栏布局 hboxLayout3->addWidget(spacelabel2); hboxLayout3->addWidget(loginbutton); hboxLayout3->addWidget(registerbutton); vboxLayout3->addWidget(spacelabel3); vboxLayout3->addLayout(hboxLayout3); hboxLayout2->addStretch(); hboxLayout2->addLayout(vboxLayout3); //将标题图片和标签窗口加入总布局 vboxLayout0->addWidget(titleImage); vboxLayout0->addWidget(mainTabWidget); //总窗口显示 window->setAutoFillBackground(true); window->setLayout(vboxLayout0); window->setWindowTitle(tr("图书管理系统")); window->setFixedSize(1024*1.2,768*1.2); window->show(); } /* 登录窗口布局 */ void database::setWindowLogin() { //登录时禁用登录和注册按钮 loginbutton->setDisabled(true); registerbutton->setDisabled(true); //新建用户和管理员登录窗口 user_loginWidget = createLoginWindow(1); manager_loginWidget = createLoginWindow(2); //加入两个登录窗口加入分栏布局,并显示 loginTabWidget = new QTabWidget(); loginTabWidget->addTab(user_loginWidget,"用户登录"); loginTabWidget->addTab(manager_loginWidget,"管理员登录"); //禁用关闭按钮 loginTabWidget->setWindowFlags(loginTabWidget->windowFlags()&~Qt::WindowCloseButtonHint); loginTabWidget->show(); } /* 搜索书籍界面布局 */ void database::setWindowSearchBook(int type) { //如果身份为用户,需要销毁之前的窗口新建 if(type==USER_LOGIN||type==USER_REGISTER){ delete window1; } //常量 const int num = 8; const int columnNum = 3; const int typenum =23; //申请内存 window1 = new QWidget(); gridLayout = new QGridLayout(); vboxLayout1 = new QVBoxLayout(); vboxLayout = new QVBoxLayout(); hboxLayout1 = new QHBoxLayout(); hboxLayout = new QHBoxLayout(); groupbox = new QGroupBox(); groupbox1 = new QGroupBox(); clearbutton = new QPushButton(tr("清空")); searchbutton = new QPushButton(tr("搜索")); tablewidget = new QTableWidget(); tree = new QTreeWidget(); root = new QTreeWidgetItem(QStringList()<<"所有类型"); QTreeWidgetItem *leaf[typenum]; //建立信号与槽 connect(searchbutton,SIGNAL(clicked()),this,SLOT(searchBook())); //点击搜索按钮,进行搜索操作 connect(clearbutton,SIGNAL(clicked()),this,SLOT(clear())); //点击清除按钮,进行清除操作 connect(tree,SIGNAL(itemClicked(QTreeWidgetItem*,int)), this,SLOT(searchBookByType(QTreeWidgetItem*,int))); //点击树状列表,进行查找书籍操作 //更新窗口信息 updateTitle(type); //设置左边的树状图书分类栏 tree->setHeaderLabels(QStringList()<<"图书类型"); tree->addTopLevelItem(root); tree->setFixedWidth(280); tree->setColumnWidth(1,10); QString str2[] = { "马列主义毛邓思想","哲学","社会科学总论","政治法律","军事","经济","文化科学体育教育","语言文字", "文学","艺术","历史地理","自然科学总论","数理科学与化学","天文学与地理科学","生物科学","医药卫生", "工业技术","交通运输","航空航天","环境科学" }; for(int i=0;i<20;i++){ leaf[i] = new QTreeWidgetItem(QStringList()<<str2[i]); root->addChild(leaf[i]); } tree->expandAll(); //设置高级搜索栏 window = new QWidget(); nameLine = new QLineEdit(); publishLine = new QLineEdit(); authorLine = new QLineEdit(); dateBox = new QComboBox(); dateBox1 = new QComboBox(); priceLine = new QLineEdit(); priceLine1 = new QLineEdit(); isLent = new QComboBox(); label = new QLabel[num]; QString str[] = {"书名","出版社","作者","年份"," --","状态","价位"," --"}; for(int i=0;i<num;i++){ label[i].setText(str[i]); gridLayout->addWidget(label+i,i/columnNum+1,2*(i%columnNum)+1); } dateBox->addItem(" "); dateBox1->addItem(" "); for(int i=0;i<60;i++){ dateBox->addItem(QString::number(2016-i)); dateBox1->addItem(QString::number(2016-i)); } isLent->addItem(" "); isLent->addItem("已借出"); isLent->addItem("未借出"); //表格布局,放置搜索选项 gridLayout->addWidget(nameLine,1,2); //书名 gridLayout->addWidget(publishLine,1,4); //类型 gridLayout->addWidget(authorLine,1,6); //作者名称 gridLayout->addWidget(dateBox,2,2); //年份(起) gridLayout->addWidget(dateBox1,2,4); //年份(终) gridLayout->addWidget(isLent,2,6); //借阅状态 gridLayout->addWidget(priceLine,3,2); //价格(从) gridLayout->addWidget(priceLine1,3,4); //价格(到) //搜索选项加入群组中 groupbox->setLayout(gridLayout); groupbox->setFixedSize(600,140); //垂直布局,放置两个按钮 vboxLayout1->addStretch(); vboxLayout1->addWidget(searchbutton); vboxLayout1->addWidget(clearbutton); vboxLayout1->addStretch(); groupbox1->setLayout(vboxLayout1); groupbox1->setFixedSize(200,140); //水平布局,依次加入搜索选项和按钮的垂直布局 hboxLayout1->addWidget(groupbox); hboxLayout1->setSpacing(30); hboxLayout1->addWidget(groupbox1); //垂直布局,依次加入搜索框和显示框 vboxLayout->addLayout(hboxLayout1); vboxLayout->addWidget(tablewidget); setWindowShowBook(type); vboxLayout->addLayout(hboxLayout6); //水平布局,加入左边栏和右窗口 hboxLayout->addWidget(tree); hboxLayout->addLayout(vboxLayout); //窗口1加入水平布局 window1->setLayout(hboxLayout); mainTabWidget->addTab(window1,"图书搜索"); //如果对象为用户,那么新建借书窗口 if(type==USER_LOGIN||type==USER_REGISTER){ setWindowLoanBook(); } } /* 单册添加书籍界面布局 */ void database::setWindowAddBook() { //申请内存 QLabel *label3 = new QLabel; label3->setText("(如果有多个作者,请用空格分开)"); addBookWidget = new QWidget(); deletebookWidget = new QWidget(); window3 = new QWidget(); vboxLayout4 = new QVBoxLayout(); vboxLayout5 = new QVBoxLayout(); vboxLayout6 = new QVBoxLayout(); vboxLayout9 = new QVBoxLayout(); hboxLayout4 = new QHBoxLayout(); hboxLayout5 = new QHBoxLayout(); hboxLayout9 = new QHBoxLayout(); deleteOkButton = new QPushButton("确定"); manageTabWidget = new QTabWidget(); gridLayout2 = new QGridLayout(); okbutton = new QPushButton(tr("确定")); nameLine2 = new QLineEdit(); typeBox2 = new QComboBox(); priceLine2 = new QLineEdit(); authorLine2 = new QLineEdit(); numLine2 = new QLineEdit(); publishLine2 = new QLineEdit(); dateBox2 = new QComboBox(); idLine = new QLineEdit(); label2 = new QLabel[7]; label5 = new QLabel; label5->setText("请输入待删除书目的编号"); //建立信号与槽 connect(deleteOkButton,SIGNAL(clicked()),this,SLOT(deleteBook())); //点击确认删除按钮,进行删除书籍操作 connect(okbutton,SIGNAL(clicked()),this,SLOT(oneAddBook())); //点击确认按钮,进行添加书本操作 //设置选项框信息 QString str[7] = {"书名","价格","数量","出版社","出版日期", "分类","作者"}; QString str2[20] = { "马列主义毛邓思想","哲学","社会科学总论","政治法律","军事","经济","文化科学体育教育","语言文字", "文学","艺术","历史地理","自然科学总论","数理科学与化学","天文学与地理科学","生物科学","医药卫生", "工业技术","交通运输","航空航天","环境科学" }; for(int i = 0;i < 7;i++){ label2[i].setText(str[i]); } for(int i=0;i<20;i++){ typeBox2->addItem(str2[i]); } for(int i=0;i<60;i++){ dateBox2->addItem(QString::number(2016-i)); } //窗口布局 //设置选项框表格 gridLayout2->addWidget(label2,1,1); gridLayout2->addWidget(label2+1,1,3); gridLayout2->addWidget(label2+2,2,1); gridLayout2->addWidget(label2+3,2,3); gridLayout2->addWidget(label2+4,3,1); gridLayout2->addWidget(label2+5,3,3); gridLayout2->addWidget(label2+6,4,1); gridLayout2->addWidget(nameLine2,1,2); gridLayout2->addWidget(priceLine2,1,4); gridLayout2->addWidget(numLine2,2,2); gridLayout2->addWidget(publishLine2,2,4); gridLayout2->addWidget(dateBox2,3,2); gridLayout2->addWidget(typeBox2,3,4); gridLayout2->addWidget(authorLine2,4,2); gridLayout2->addWidget(label3,4,3,1,2); //加入确认按钮 hboxLayout5->addStretch(); hboxLayout5->addWidget(okbutton); hboxLayout5->addStretch(); vboxLayout6->addLayout(gridLayout2); vboxLayout6->addLayout(hboxLayout5); addBookWidget->setLayout(vboxLayout6); hboxLayout9->addStretch(); hboxLayout9->addWidget(deleteOkButton); hboxLayout9->addStretch(); vboxLayout9->addStretch(); vboxLayout9->addWidget(label5); vboxLayout9->addWidget(idLine); vboxLayout9->addLayout(hboxLayout9); vboxLayout9->addStretch(); //添加分页窗口 deletebookWidget->setLayout(vboxLayout9); manageTabWidget->addTab(addBookWidget,"添加图书"); manageTabWidget->addTab(deletebookWidget,"删除书籍"); vboxLayout5->addSpacing(100); vboxLayout5->addWidget(manageTabWidget); vboxLayout5->addSpacing(300); hboxLayout4->addStretch(); hboxLayout4->addLayout(vboxLayout5); hboxLayout4->addStretch(); window3->setLayout(hboxLayout4); } /* 多册添加书籍界面布局 */ void database::setWindowMutiAddBook() { //申请内存 tipLabel = new QLabel(); window5 = new QWidget(); tablewidget3 = new QTableWidget(); vboxLayout12 = new QVBoxLayout(); hboxLayout12 = new QHBoxLayout(); hboxLayout13 = new QHBoxLayout(); addBookOkButton = new QPushButton("提交表单"); addBookClearButton = new QPushButton("清空表单"); loadFileButton = new QPushButton("加载文件"); //建立信号与槽 connect(addBookOkButton,SIGNAL(clicked()),this,SLOT(mutiAddBook())); connect(addBookClearButton,SIGNAL(clicked()),this,SLOT(clearAddBookMessage())); connect(loadFileButton,SIGNAL(clicked()),this,SLOT(openFile())); //设置选项信息 tipLabel->setText("请双击表格进行内容填写,或者通过文本加载。" "如果有多个作者,请用空格分开\n" "文本格式:按表格属性填写,同样属性按空格分开。" "输入下本书籍信息要换行区分"); tipLabel->setFrameShape (QFrame::Box); QStringList header; tablewidget3->setRowCount(13); tablewidget3->setColumnCount(7); header<<"书名"<<"价格"<<"数量"<<"出版社"<<"出版日期"<<"分类"<<"作者"; //初始化表格信息 for(int i=0;i<13;i++){ for(int j=0;j<7;j++){ if(j==4){ publishDate[i] = new QComboBox(); for(int k=0;k<60;k++){ publishDate[i]->addItem(QString::number(2016-k)); } tablewidget3->setCellWidget(i,j,publishDate[i]); } else if(j==5){ QString str[] = { "马列主义毛邓思想","哲学","社会科学总论","政治法律","军事","经济","文化科学体育教育","语言文字", "文学","艺术","历史地理","自然科学总论","数理科学与化学","天文学与地理科学","生物科学","医药卫生", "工业技术","交通运输","航空航天","环境科学" }; bookType[i] = new QComboBox(); for(int k=0;k<20;k++){ bookType[i]->addItem(str[k]); } tablewidget3->setCellWidget(i,j,bookType[i]); } else{ QTableWidgetItem *item = new QTableWidgetItem(""); tablewidget3->setItem(i,j,item); } } } tablewidget3->setHorizontalHeaderLabels(header); //加入按钮和表格 hboxLayout12->addStretch(); hboxLayout12->addWidget(addBookOkButton); hboxLayout12->addWidget(addBookClearButton); hboxLayout13->addWidget(tipLabel); hboxLayout13->addWidget(loadFileButton); vboxLayout12->addLayout(hboxLayout13); vboxLayout12->addWidget(tablewidget3); vboxLayout12->addLayout(hboxLayout12); window5->setLayout(vboxLayout12); } /* 借阅书籍界面布局 */ void database::setWindowLoanBook() { //申请内存 window4 = new QWidget(); mainTabWidget->addTab(window4,"借阅情况"); tablewidget2 = new QTableWidget(3,7); hboxLayout11 = new QHBoxLayout(); vboxLayout11 = new QVBoxLayout(); returnBookButton = new QPushButton("归还书籍"); //建立信号与槽 connect(returnBookButton,SIGNAL(clicked()),this,SLOT(returnBook())); //点击还书按钮,进行还书操作 //加入按钮和表格 hboxLayout11->addStretch(); hboxLayout11->addWidget(returnBookButton); hboxLayout11->addStretch(); vboxLayout11->addWidget(tablewidget2); vboxLayout11->addLayout(hboxLayout11); vboxLayout11->addStretch(); window4->setLayout(vboxLayout11); //更新借阅表格 updateLoanBookWindow(); } /* 用户管理界面布局 */ void database::setWindowUserManage() { //申请内存 lastPageButton = new QPushButton("上一页"); nextPageButton = new QPushButton("下一页"); deleteUserButton = new QPushButton("删除用户信息"); grantLentButton = new QPushButton("授予/删除借书权限"); tablewidget1 = new QTableWidget(13,11); window2 = new QWidget(); hboxLayout10 = new QHBoxLayout(); vboxLayout10 = new QVBoxLayout(); //建立信号与槽 connect(lastPageButton,SIGNAL(clicked()),this,SLOT(userLastPage())); //点击上一页按钮,翻到上一页 connect(nextPageButton,SIGNAL(clicked()),this,SLOT(userNextPage())); //点击下一页按钮,翻到下一页 connect(deleteUserButton,SIGNAL(clicked()),this,SLOT(deleteUser())); //点击删除用户按钮,进行删除用户操作 connect(grantLentButton,SIGNAL(clicked()),this,SLOT(grantLent())); //点击借书授权按钮,进行借书授权操作 //载入用户信息,并更新用户管理表格 loadUserMessage(); updateManageWindow(); //加入按钮 hboxLayout10->addStretch(); hboxLayout10->addWidget(deleteUserButton); hboxLayout10->addWidget(grantLentButton); hboxLayout10->addWidget(lastPageButton); hboxLayout10->addWidget(nextPageButton); //布局 vboxLayout10->addWidget(tablewidget1); vboxLayout10->addLayout(hboxLayout10); window2->setLayout(vboxLayout10); } /* 用户注册界面布局 */ void database::setWindowRegister() { //申请内存 registerWindow = new QWidget(); gridLayout3 = new QGridLayout(); label4 = new QLabel[3]; label4[0].setText("用户名"); label4[1].setText("密码"); label4[2].setText("密码确认"); label3 = new QLabel("请输入注册信息(借书权\n" "限将由管理员添加)"); nameLine3 = new QLineEdit(); passwordLine1 = new QLineEdit(); passwordLine2 = new QLineEdit(); passwordLine1->setEchoMode(QLineEdit::Password); passwordLine2->setEchoMode(QLineEdit::Password); registerOkButton = new QPushButton("确定"); hboxLayout7 = new QHBoxLayout(); hboxLayout8 = new QHBoxLayout(); vboxLayout7 = new QVBoxLayout(); //页面布局 hboxLayout7->addStretch(); hboxLayout7->addWidget(registerOkButton); hboxLayout7->addStretch(); gridLayout3->addWidget(&label4[0],1,1); gridLayout3->addWidget(&label4[1],2,1); gridLayout3->addWidget(&label4[2],3,1); gridLayout3->addWidget(nameLine3,1,2); gridLayout3->addWidget(passwordLine1,2,2); gridLayout3->addWidget(passwordLine2,3,2); vboxLayout7->addWidget(label3); vboxLayout7->addLayout(gridLayout3); vboxLayout7->addLayout(hboxLayout7); hboxLayout8->addStretch(); hboxLayout8->addLayout(vboxLayout7); hboxLayout8->addStretch(); registerWindow->setLayout(hboxLayout8); registerWindow->resize(400,300); registerWindow->show(); //建立信号与槽 connect(registerOkButton,SIGNAL(clicked()),this,SLOT(Register())); //点击确认登录按钮,进行登录操作 } /* 显示书籍信息界面布局 */ void database::setWindowShowBook(int type) { //申请内存 hboxLayout6 = new QHBoxLayout(); lastbutton = new QPushButton(tr("上一页")); nextbutton = new QPushButton(tr("下一页")); //建立信号与槽 connect(lastbutton,SIGNAL(clicked()),this,SLOT(bookLastPage())); //点击上一页按钮,翻到上一页 connect(nextbutton,SIGNAL(clicked()),this,SLOT(bookNextPage())); //点击下一页按钮,翻到下一页 //页面布局 hboxLayout6->addStretch(); hboxLayout6->addWidget(lastbutton); hboxLayout6->addWidget(nextbutton); //如果当前使用者为用户,加入借阅书籍按钮 if(type==USER_LOGIN||type==USER_REGISTER){ lendBookButton = new QPushButton(tr("借阅书籍")); connect(lendBookButton,SIGNAL(clicked()),this,SLOT(lendBook())); hboxLayout6->addWidget(lendBookButton); } //初始化当前页和最大页 current_page = 1; max_page = 1; //更新显示书目窗口 updateShowBookWindow(); } /* 更新书籍信息界面 */ void database::updateShowBookWindow() { QStringList header; //清除表格信息 tablewidget->clear(); //设置表格为不可选择、不可修改 tablewidget->setEditTriggers(QAbstractItemView::NoEditTriggers); tablewidget->setSelectionMode(QAbstractItemView::NoSelection); //根据当前使用者的不同使用不同的标题栏 if(user_type==USER){ tablewidget->setRowCount(10); tablewidget->setColumnCount(11); header<<""<<"编号"<<"书名"<<"价格"<<"库存"<<"入库时间" <<"入库人员"<<"出版社"<<"出版年份"<<"类型"<<"作者"; } else{ tablewidget->setRowCount(10); tablewidget->setColumnCount(10); header<<"编号"<<"书名"<<"价格"<<"库存"<<"入库时间" <<"入库人员"<<"出版社"<<"出版年份"<<"类型"<<"作者"; } //加入标题栏 tablewidget->setHorizontalHeaderLabels(header); //设置宽度 for(int i=0;i<10;i++){ tablewidget->setColumnWidth(i,120); } //求出当前页的最多显示条目 int max; if(result.length()==0)return; if(current_page==max_page){ max = result.length()%100/10; if(max==0)max=10; } else max = 10; //根据当前使用者的不同在表格上显示不同信息 if(user_type==USER){ for(int i=0;i<max;i++){ item2[i] = new QTableWidgetItem(); item2[i]->setCheckState(Qt::Unchecked); item3[i] = new QTableWidgetItem(result.at(10*i+100*(current_page-1))); tablewidget->setItem(i,0,item2[i]); tablewidget->setItem(i,1,item3[i]); for(int j=1;j<10;j++){ QTableWidgetItem *item = new QTableWidgetItem(result.at(10*i+j+100*(current_page-1))); tablewidget->setItem(i,j + 1,item); } } } else{ for(int i=0;i<max;i++){ for(int j=0;j<10;j++){ QTableWidgetItem *item = new QTableWidgetItem(result.at(10*i+j+100*(current_page-1))); tablewidget->setItem(i,j,item); } } } } /* 更新借阅书籍界面 */ void database::updateLoanBookWindow() { //更新前加载借阅信息 loadLoanMessage(); QStringList header; //清空表格信息 tablewidget2->clear(); //设置标题栏 header<<""<<"书本编号"<<"书本名称"<<"借阅日期"<<"单册编号"<<"最晚归还日期"<<"剩余归还天数"; tablewidget2->setHorizontalHeaderLabels(header); //设置表格为不可修改,不可选择 tablewidget2->setEditTriggers(QAbstractItemView::NoEditTriggers); tablewidget2->setSelectionMode(QAbstractItemView::NoSelection); //将信息显示到表格上 for(int i=0;i<loanMessage.length();i++){ item4[i] = new QTableWidgetItem(); item4[i]->setCheckState(Qt::Unchecked); tablewidget2->setItem(i,0,item4[i]); for(int j=0;j<6;j++){ QTableWidgetItem *item = new QTableWidgetItem(loanMessage.at(i)[j]); tablewidget2->setItem(i,j + 1,item); } } } /* 更新用户管理界面 */ void database::updateManageWindow() { //计算当前页面能显示的最多用户数 int max; if(user_current_page==user_max_page){ max = (user_num%13==0)?13:user_num%13; } else{ max = 13; } //清除表格信息 tablewidget1->clear(); //设置表格为不可选择,不可修改 tablewidget1->setEditTriggers(QAbstractItemView::NoEditTriggers); tablewidget1->setSelectionMode(QAbstractItemView::NoSelection); //设置标题栏 QStringList header; header<<""<<"用户名"<<"密码"<<"借书权限"<<"借阅数目"<<"借阅书籍1" <<"借阅日期"<<"借阅书籍2"<<"借阅日期"<<"借阅书籍3"<<"借阅日期"; tablewidget1->setHorizontalHeaderLabels(header); //将信息显示到表格上 for(int i=0;i<max;i++){ int row = i + (user_current_page - 1)*13; item0[i] = new QTableWidgetItem(); item0[i]->setCheckState(Qt::Unchecked); item1[i] = new QTableWidgetItem(userMessage.at(row)[0]); tablewidget1->setItem(i,0,item0[i]); tablewidget1->setItem(i,1,item1[i]); for(int j=1;j<10;j++){ QTableWidgetItem *item = new QTableWidgetItem(userMessage.at(row)[j]); tablewidget1->setItem(i,j+1,item); } } } /* 更新时间显示 */ void database::updateTime() { //获取系统时间 QDateTime current_date_time = QDateTime::currentDateTime(); QString current_date = current_date_time.toString("yyyy-MM-dd hh:mm:ss ddd"); QString text = "当前用户: " + current_user + " | 当前时间:"+current_date+" "; spacelabel2->setText(text); } /* 更新标题栏信息 */ void database::updateTitle(int type) { //获取系统时间 QDateTime current_date_time = QDateTime::currentDateTime(); QString current_date = current_date_time.toString("yyyy-MM-dd hh:mm:ss ddd"); QString text; //如果当前使用者为游客,更新标题栏,直接返回 if(type==VISITOR){ text = "当前用户:游客 | 当前时间:"+current_date+" "; spacelabel2->setText(text); return; } //登录后删除登录、注册按钮 delete loginbutton; delete registerbutton; //新建退出登录按钮,点击退出登录按钮,进行退出登录操作 quitloginbutton = new QPushButton("退出登录"); connect(quitloginbutton,SIGNAL(clicked()),this,SLOT(quitLogin())); hboxLayout3->addWidget(quitloginbutton); quitloginbutton->setFlat(true); //根据当前使用者显示不同的标题栏 if(type==USER_LOGIN){ text = "当前用户:"+username1->text()+" | 当前时间:"+current_date+" "; current_user = username1->text(); user_type = USER; //删除登录窗口 delete loginTabWidget; } else if(type==USER_REGISTER){ text = "当前用户:"+nameLine3->text()+" | 当前时间:"+current_date+" "; current_user = nameLine3->text(); user_type = USER; //删除注册窗口 delete registerWindow; } else if(type==MANAGER){ text = "当前用户:"+username2->text()+" | 当前时间:"+current_date+" "; current_user = username2->text(); user_type = MANAGER; //删除登录窗口 delete loginTabWidget; } spacelabel2->setText(text); } /* 创建登录窗口(登录窗口布局的辅助函数) */ QWidget* database::createLoginWindow(int type) { //申请内存 QWidget *widget = new QWidget(); QLabel *username_label = new QLabel; QLabel *password_label = new QLabel; QGridLayout *glayout = new QGridLayout; QPushButton *yesbutton = new QPushButton(tr("确定")); QPushButton *quitbutton = new QPushButton(tr("退出")); QHBoxLayout *hlayout = new QHBoxLayout(); QVBoxLayout *vlayout = new QVBoxLayout(); //根据不同类型建立不同的输入栏 if(type==1){ username1 = new QLineEdit(); password1 = new QLineEdit(); password1->setEchoMode(QLineEdit::Password); glayout->addWidget(username1,1,2); glayout->addWidget(password1,2,2); } else if(type==2){ username2 = new QLineEdit(); password2 = new QLineEdit(); password2->setEchoMode(QLineEdit::Password); glayout->addWidget(username2,1,2); glayout->addWidget(password2,2,2); } username_label->setText(tr("账号")); password_label->setText(tr("密码")); //表格布局加入文字标签 glayout->setContentsMargins(50,100,50,100); glayout->setSpacing(40); glayout->addWidget(username_label,1,1); glayout->addWidget(password_label,2,1); //加入按钮和输入栏 hlayout->addStretch(); hlayout->addWidget(yesbutton); hlayout->addWidget(quitbutton); hlayout->addStretch(); vlayout->addLayout(glayout); vlayout->addLayout(hlayout); widget->setLayout(vlayout); //点击退出按钮,进行删除登录窗口操作 connect(quitbutton,SIGNAL(clicked()),this,SLOT(deleteLogin())); //点击确认按钮,根据类型不同将信号发送到用户登录和管理员登录中 if(type==1){ connect(yesbutton,SIGNAL(clicked()),this,SLOT(userLogin())); } else if(type==2){ connect(yesbutton,SIGNAL(clicked()),this,SLOT(managerLogin())); } return widget; } /* 清空搜索框 */ void database::clear() { nameLine->clear(); publishLine->clear(); authorLine->clear(); priceLine->clear(); priceLine1->clear(); } /* 清空多册添加的表单 */ void database::clearAddBookMessage() { //对每一个表单,设置为空 for(int i = 0;i<13;i++){ for(int j = 0;j<7;j++){ if(j!=5&&j!=4){ tablewidget3->item(i,j)->setText(""); } } } //如果有图书信息缓存,清空 for(int i=0;i<multiBookMessage.length();i++){ multiBookMessage.pop_front(); } } /* 删除登录界面*/ void database::deleteLogin() { //删除登陆界面,并将登录注册按钮设为可使用 delete loginTabWidget; loginbutton->setEnabled(true); registerbutton->setEnabled(true); } /* 退出登录更新界面*/ void database::quitLogin() { //删除退出登录按钮 delete quitloginbutton; //根据当前使用者的不同,删除对应的窗口以及控件 if(user_type==MANAGER){ delete window3; delete window2; delete window5; } else if(user_type==USER){ delete window4; delete lendBookButton; } //获取系统时间 QDateTime current_date_time = QDateTime::currentDateTime(); QString current_date = current_date_time.toString("yyyy-MM-dd hh:mm:ss ddd"); QString text = "当前用户: 游客 | 当前时间:"+current_date+" "; //更新使用者类型为游客 user_type = VISITOR; current_user = "游客"; spacelabel2->setText(text); //重新建立登录注册按钮,并摆放 loginbutton = new QPushButton("登录"); registerbutton = new QPushButton("注册"); loginbutton->setFlat(true); registerbutton->setFlat(true); registerbutton->setFixedSize(QSize(60,30)); loginbutton->setFixedSize(QSize(60,30)); hboxLayout3->addWidget(loginbutton); hboxLayout3->addWidget(registerbutton); //重新连接登录注册与对应的槽函数 connect(loginbutton,SIGNAL(clicked()),this,SLOT(setWindowLogin())); connect(registerbutton,SIGNAL(clicked()),this,SLOT(setWindowRegister())); } /* 用户管理翻页(上一页)*/ void database::userLastPage() { //当前页为1,不存在上一页,返回 if(user_current_page==1)return; //当前页减1 user_current_page--; //更新用户管理窗口 updateManageWindow(); } /* 用户管理翻页(下一页)*/ void database::userNextPage() { //如果当前页面为最大页面,不存在下一页面,返回 if(user_current_page==user_max_page)return; //当前页面加一 user_current_page++; //更新用户管理窗口 updateManageWindow(); } /* 显示书籍翻页(上一页)*/ void database::bookLastPage() { //当前页为1,不存在上一页,返回 if(current_page==1)return; //当前页减1 current_page--; //更新显示书本窗口 updateShowBookWindow(); } /* 显示书籍翻页(下一页)*/ void database::bookNextPage() { //如果当前页面为最大页面,不存在下一页面,返回 if(current_page==max_page)return; //当前页面加一 current_page++; //更新显示书本窗口 updateShowBookWindow(); } /* 打开文件导入书籍数据 */ void database::openFile() { //新建文件显示窗口 fileWindow = new QWidget; QFileDialog dlg(fileWindow,"打开文本"); dlg.resize(400,300); dlg.setAcceptMode(QFileDialog::AcceptOpen); //只允许打开.txt后缀的文件 dlg.setNameFilter("*txt"); //打开文件对话框 if(dlg.exec()==QDialog::Accepted ){ QStringList files = dlg.selectedFiles(); if(!files.isEmpty()){ //以只读形式打开选中文件 QFile file; file.setFileName(files.at(0)); file.open(QIODevice::ReadOnly); if(!file.atEnd()){ int count = 0; int rowNum = 0; //读取文本所有信息,并进行转码处理 QByteArray buff; buff = file.readAll(); QString fileContent = QString::fromLocal8Bit(buff); QString str = ""; //对文本进行格式化处理 for(int k=0;k<=fileContent.length();k++){ //读到换行符或者读完文本,把书籍信息存储 if(fileContent.at(k)=='\n'||k==fileContent.length()){ bookMessage[6] = str; if(rowNum>=13){ //列数超过显示范围,暂存到容器中 QString *tmp = new QString[7]; for(int i=0;i<7;i++){ tmp[i] = bookMessage[i]; } multiBookMessage.push_back(tmp); } else{ //列数未超过显示范围,直接显示在表格中 for(int i=0;i<7;i++){ if(i==4)publishDate[rowNum]->setCurrentText(bookMessage[i]); else if(i==5)bookType[rowNum]->setCurrentText(bookMessage[i]); else{ tablewidget3->item(rowNum,i)->setText(bookMessage[i]); } } rowNum++; count = 0; str = ""; } //如果以换行符结束,不需要继续处理 if(fileContent.at(k)=='\n'&&k==fileContent.length()-1){ break; } } //读到空格且不是作者信息中的空格,跳过空格,并把字符串存储到bookmessage中 else if(fileContent.at(k)==' '&&count!=6){ bookMessage[count++] = str; str = ""; } //读到空格且是作者信息中的空格,直接存储空格信息 else if(fileContent.at(k)==' '&&count==6){ str = str + fileContent.at(k); } //读到支持的文本内容,将其加入字符串中 else if(fileContent.at(k).isLetter()||fileContent.at(k).isNumber() ||fileContent.at(k)=='.'||fileContent.at(k)==':' ||fileContent.at(k)=='-'||fileContent.at(k)=='"' ||fileContent.at(k)=='('||fileContent.at(k)==')' ||fileContent.at(k)=='·'){ str = str