基于QT的图书管理系统

课程项目实施方案

使用工具

编程语言:C++
编译器:QT Creator
数据库:SQLITE

QT:
Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。
SQLITE:
sqlite是轻量级的、嵌入式的、关系型数据库,,SQLite可移植性好,很容易使用,很小,高效而且可靠。SQLite嵌入到使用它的应用程序中,它们共用相同的进程空间,而不是单独的一个进程。在QT中集成了sqlite驱动,可以很方便调用数据库,无需像使用mysql那样设置连接密码。

设计思想

指标

模拟现有图书馆的借阅、续借、归还,图书入库、出库,查询、排序等功能,实现电子图书馆的智慧综合管理,要求:
(1) 掌握抽象数据类型的定义;
(2) 实现数据结构查找算法;
(3) 实现数据结构排序算法;
(4) 使用简单数据库操作;
(5) 友好、易操作的用户交互界面。

实现方式

数据库结构

字段名 类型 介绍 备注
Book表
id text ISBN书号 主键
name text 书名
author text 作者
pub text 出版社
pub_date text 出版日期 yyyy-MM
avail blob 是否可借 是1,否0
store integer 库存
total integer 总数
Loan表
user_id text 用户 外键
book_id text 书籍 外键
Loan_date text 借阅日期 yyyy-MM-dd
Back_date text 应还日期 yyyy-MM-dd
Manager表
id text 管理员 主键
pwd text 密码
User表
id text 用户 主键
pwd text 密码
email text 邮箱
loan integer 借阅数
max integer 可借阅数

业务逻辑

项目制作过程

数据库搭建

创建数据库

db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("library.db");

mylibrary.pro中加入QT += sql
在主窗口函数中执行上述代码即可创建一个名为library.db的数据库,windows下自动保存在C:\user\username\

操作数据库

使用SQLite管理工具SQLite Browser打开library.db,添加表和字段以及数据。

代码和功能实现

创建文件

mylibrary

  • mylibrary.pro项目文件
  • 头文件
    insert.h //录入
    mainwindow.h //主窗口
    register.h //注册
  • 源文件
    main.cpp
    insert.cpp
    mainwindow.cpp
    register.cpp
  • 界面文件
    insert.ui
    mainwindow.ui

界面布局

分别双击界面文件,打开QT设计模式,使拖拉组件,对界面布局

为了实现图形界面自适应大小和部件的动态添加和分布,这里使用了布局功能。

以下是界面部件的名称和类型:

编写槽函数

设计完界面后,需要编写按钮的回调函数,在QT中即槽函数,比较方便的方法是在ui界面中右击部件->转到槽即可生成相应的槽函数声明,然后在其中编写相应的功能即可

SQL语句实现数据库操作

QSqlQuery query;
query.exec("insert into user values('"+ui->lineEdit->text()+"','"+ui->lineEdit_2
               ->text()+"','"+ui->lineEdit_4->text()+"',0,8)");

如上代码,使用QSqlQueryexec可以在其中编写SQL语句来直接对数据库进行操作,在注册、登录、录入图书中我们使用了这种方式。

MVC架构实现数据库操作


如图为MVC的基本原理,在QT中Table View部件对应View,QSqlTableModel可以创建一个数据表model,这样的好处是用户对数据库的操作不会立即实现,而是先存在model中,然后model对数据库操作,可以防止误操作。

程序的打包发布

添加程序图标

pro文件中加入RC_ICONS = myico.ico,然后将myico.ico放在工程文件夹中编译即可

打包

程序调试后,可以对程序进行编译,编译后会生成一个编译文件夹,新创建一个程序文件夹,将编译文件夹中的exe文件复制到程序文件夹,在cmd中定位到该文件夹,执行命令

windeployqt mylibrary.exe

即可自动生成程序依赖库,之后点击exe即可运行。

制作过程中的问题和技巧

  • 中文编码问题
    在QT中编写代码时使用中文无法通过编译,包括输入的中文注释和中文提示,但界面中的中文并不会出现这种问题
    解决
    将所有使用中文字符的文件编码改为不带BOM的UTF-8格式,然后在使用中文字符的cpp文件的头文件中加入一段声明
    #pragma execution_character_set("utf-8")
    
  • 动态显示tabWiget的存取问题
    tabWigettab的动态显示并不能使用hideshow实现,而是使用addTabremoveTab实现的,而tab的存取是要符合堆栈的,即只能
    ui->tabWidget->removeTab(3);
    ui->tabWidget->removeTab(2);
    ui->tabWidget->removeTab(1);
    
    反过来则不能全部移除
  • 使用枚举类取代数字
    由于数据库列数使用数字代表的,为了在调用各列时清晰方便,我们使用了枚举类代替了这些数字,即
    enum BkIndex{BkId=0,BkName=1,BkAuthor=2,BkPub=3,BkPubDate=4,BkAvail=5,BkStore=6,BkTotal=7};
    
    用户类型我们也使用了这种方法
    enum{MANAGER,USER,VISITOR};
    

附录

使用的函数

函数 说明
QSqlTableModel setTable 设置数据表
setEditStrategy Model策略
setSort 排序
setHeaderData 设置字段名称
select 建立表
setModel 设置model
setFilter 查询
revertAll 恢复修改
submitAll 提交修改
removeRow 删除行
record 提取数据
insertRecord 插入数据
setData 修改数据
rowCount 行数
QSqlDatabase QSqlDatabase 创建数据库
QSqlQuery exec 运行SQL语句
isActive 判断是否执行SQL
next 提取查询的第一条数据
QDate currentDate 当前时间
addMonths 添加月数
vaddDays 添加天数
fromString 字符转换时间
QSqlRecord setValue 修改数据

部分代码

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#pragma execution_character_set("utf-8")

#include "register.h" 
#include "insert.h"
#include <QMainWindow>
#include <QDebug>
#include <QtSql>
#include <QSqlDatabase>
#include <QSqlTableModel>
#include <QMessageBox>
#include <QString>
#include <QSqlError>
#include <QDateTime>
#include <QDate>
#include <QTimer>
#include <QSqlRecord>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow(); //析构


private:
    QSqlTableModel *BkModel;       //图书model
    QSqlTableModel *UsrModel;      //用户model
    QSqlTableModel *LoanModel;     //借阅model
    QSqlTableModel *UsrLoanModel;  //用户借阅信息model
    Ui::MainWindow *ui;
    QSqlDatabase db;  //数据库
    QTimer *timer;

    int user_type;  //用户类型
    int book_store; //书籍库存
    QString id;

    enum BkIndex  //枚举书籍序号
    {
        BkId=0,
        BkName=1,
        BkAuthor=2,
        BkPub=3,
        BkPubDate=4,
        BkAvail=5,
        BkStore=6,
        BkTotal=7

    };

    enum UsrIndex  //枚举用户序号
    {
        UsrId=0,
        UsrPwd=1,
        UsrEmail=2,
        UsrLoan=3,
        UsrMax=4
    };

    enum LoanIndex  //枚举借阅序号
    {
        LUsrId=0,
        LBkId=1,
        LDate=2,
        LBackDate=3
    };

    enum{MANAGER,USER,VISITOR}; //枚举用户类型

public:
    bool dbConnect();  //数据库连接
    bool dbCreat();   //数据库创建
    void UsrLogin();  //用户登录
    void UiUpdate();  //更新界面
    void MngLogin();  //管理员登录


private slots:
    void on_pushButton_9_clicked();   //登录
    void on_pushButton_10_clicked();  //注册
    void on_pushButton_4_clicked();   //录入书籍
    void on_pushButton_11_clicked();  //注销
    void on_pushButton_5_clicked();   //提交
    void on_pushButton_3_clicked();   //删除
    void on_pushButton_6_clicked();   //撤销
    void on_pushButton_7_clicked();   //删除用户
    void on_pushButton_12_clicked();  //提交用户修改
    void on_pushButton_13_clicked();  //撤销用户修改
    void on_pushButton_2_clicked();   //借阅
    void on_pushButton_15_clicked();  //还书
    void on_pushButton_14_clicked();  //续借
    void on_pushButton_clicked();     //书名查询
    void on_pushButton_16_clicked();  //作者查询
    void on_pushButton_8_clicked();   //用户查询
    void on_pushButton_18_clicked();  //返回主表
    void on_pushButton_17_clicked();  //返回主表
};


#endif // MAINWINDOW_H