基于Qt的实验室管理系统的设计(作业)

观前提要: 本项目是大学学习Qt时的结课作业,发出来记录一下(博客=大型网盘),所以技术上并不适合正式使用,仅学习参考
其中的数据库内容很稀烂,全是自己瞎鼓捣的,所以非常复杂繁琐
类的使用也很稀烂,本人在做这个时没学C++,有关这些部分基本上是参考+改编

基本功能

  1. 使用QSQLITE数据库完成数据库的设计。
  2. 注册功能:包含学生注册,教师教辅人员注册,实验室管理员注册。
  3. 忘记密码的功能。
  4. 学生和老师以及实验室管理员的分别登陆后的权限不同,进入到不同的管理页面。
  5. 管理员页面可以完成实验室教师信息的增删改查功能。
  6. 学生注册后管理员可以查看修改删除学生的信息
  7. 管理员界面完成实验室分布情况的增删改查功能,提供实验室可以预约的人数。
  8. 学生注册登录后可以实现学生信息的完善,学生只可以查看和修改自己的信息,不可删除。
  9. 学生端完成实验室课程的预约,每一个学生完成预约,数据库中的可预约人数相应减少一个,只到实验室人数预约满了,该实验室不可再预约。

其他花里胡哨的小功能放下一期
1.显示密码/隐藏密码
2. 将成功登录的账号加入下拉框,以便下一次登录
3.ui设计

流程图(这个很有点水,不建议看,当时为了交作业粗制滥造的)

在这里插入图片描述

功能实现

数据库连接

数据库连接

// 数据库连接
CreatDatabase();
    bool ok = db.open();
    if (ok)
    {
        qDebug() << "database connect is ok";
    }
    else
    {
        qDebug() << "database connect is fail";
    }
    createTable("CREATE TABLE admin(id INTEGER PRIMARY KEY,name TEXT,password varchar(20),role int)");
    createTable("CREATE TABLE student(id INTEGER PRIMARY KEY,name TEXT,institute TEXT,password varchar(20),role int,labid int)");
    createTable("CREATE TABLE teacher(id INTEGER PRIMARY KEY,name TEXT,password varchar(20),role int)");
    createTable("CREATE TABLE lab(id INTEGER PRIMARY KEY,name TEXT,total int,num int)");

创建数据库函数

// 创建数据库函数
void login::CreatDatabase()
{
    // 创建一个数据库连接,指定数据库驱动
    db = QSqlDatabase::addDatabase("QSQLITE");

    // 数据库连接需要设置的信息
    db.setHostName("127.0.0.1"); // 数据库服务器IP,我用的是本地电脑
    db.setDatabaseName("Labsys.db");// 数据库名
    db.setUserName("root");// 用户名
    db.setPassword("123456");// 密码
    db.setPort(3306);// 端口号
}

建表函数

// 建表函数
void login::createTable(QString SQLcreateTable)
{
    // 创建一个表
    QString sql = SQLcreateTable;

    // 实例化QSqlQuery,用于执行sql语句
    QSqlQuery sq;

    if(sq.exec(sql)){   //执行SQL的成功or失败
        qDebug()<<"建表成功!";
    }else{
        qDebug()<<sq.lastError().text(); //输出错误信息
    }
}

注册页面(signup)

(数据库在登录页面)

  1. 通过对comboBox_ide的检索,判断注册的身份
  2. 用3个if分别插入数据库(每个if里insert的表不同,和随机生成的学工号长度不同)
  3. 用随机数生成学工号长度,管理员为2位,教师为4位,学生为7位
  4. 注册成功弹出新窗口,上面通过父窗口向子窗口传值的方法(getLastWindow函数)将随机生成的学工号和用户输入的姓名密码显示在新窗口(succeed)上,实现反馈效果

参考:父窗口向子窗口传值

请添加图片描述
注册功能:包含学生注册,教师教辅人员注册,实验室管理员注册。

// 注册功能
void signup::on_pbt_signup_clicked()
{
    int flag1 = ui->comboBox_ide->currentIndex();

    if(flag1 == 0){
        int role = 0;
        int id = generateRandomNumber(1,99); //在1到99内生成一个数
        QString name = ui->lineEdit_name->text();
        QString password = ui->lineEdit_password->text();
        if(name == "")
            QMessageBox::warning(this,"","学工号不能为空!");
        else if(password == "")
            QMessageBox::warning(this,"","密码不能为空!");
        else{
            bool flag = insertadmin(db,id,name,password,role);
            if(flag){

                succeed *page_succeed = new succeed();
                page_succeed->getLastWindow(role,id,name,password);
                page_succeed->show();
                this->hide();

                connect(page_succeed,&succeed::back,[=](){
                    page_succeed->close();
                    this->show();
                    emit this->back();
                });

            }else
                QMessageBox::information(this,tr("提示"),tr("注册失败!"));
        }

    }else if(flag1 == 1){
        int role = 1;
        int id = generateRandomNumber(1001,9999);//在1001到9999内生成一个数
        QString name = ui->lineEdit_name->text();
        QString password = ui->lineEdit_password->text();

        if(name == "")
            QMessageBox::warning(this,"","学工号不能为空!");
        else if(password == "")
            QMessageBox::warning(this,"","密码不能为空!");
        else{

            bool flag = insertteach(db,id,name,password,role);
            if(flag){
                succeed *page_succeed = new succeed();
                page_succeed->getLastWindow(role,id,name,password);
                page_succeed->show();
                this->hide();

                connect(page_succeed,&succeed::back,[=](){
                    page_succeed->close();
                    this->show();
                    emit this->back();
                });
            }
            else
                QMessageBox::information(this,tr("提示"),tr("注册失败!"));
        }

    }else if(flag1 == 2){
        int role = 2;
        int id = generateRandomNumber(1000001,9999999);//在1000001到9999999内生成一个数
        QString name = ui->lineEdit_name->text();
        QString password = ui->lineEdit_password->text();

        if(name == "")
            QMessageBox::warning(this,"","学工号不能为空!");
        else if(password == "")
            QMessageBox::warning(this,"","密码不能为空!");
        else{
            bool flag = insertstud(db,id,name,password,role);
            if(flag){
                succeed *page_succeed = new succeed();
                page_succeed->getLastWindow(role,id,name,password);
                page_succeed->show();
                this->hide();

                connect(page_succeed,&succeed::back,[=](){
                    page_succeed->close();
                    this->show();
                    emit this->back();
                });
            }
            else
                QMessageBox::information(this,tr("提示"),tr("注册失败!"));
        }
    }
}

相关函数

// 插入注册信息到数据库
int signup::insertadmin(QSqlDatabase db,const int &userid, QString &name,const QString &password,int &role)
{
    QSqlQuery query(db);
    query.prepare("INSERT INTO admin (id,name,password,role) VALUES (:id,:name,:password,:role)");
    query.bindValue(":id", userid);
    query.bindValue(":name", name);
    query.bindValue(":password",password);
    query.bindValue(":role",role);
    query.exec();
}
// 生成随机数
int signup::generateRandomNumber(int min,int max)  //在min和max内生成一个随机数
{
    qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()));
    int num = qrand()%(max-min)+min;
    qDebug()<<num;
    return num;
}

找回密码(re_pwd)

1.通过检测输入框和数据库信息匹对,如果成功就将数据库内密码更新为新密码

这个功能非常半成品,检测什么都没做,如果要完善的话可以加一个验证邮箱或者验证密保(数据库里面又要加一栏了)。还可以结合网络通信搞个验证码验证(我不会)
请添加图片描述
修改密码

// 修改密码
bool re_pwd::MatchData()
{
    int flag1 = ui->comboBox_ide->currentIndex();
    QSqlQuery query;
    int userid = ui->lineEdit_id->text().toUInt();
    QString password = ui->lineEdit_password->text();
    bool found = false;
    if(flag1 == 0){
        if(QString::number(userid) == "")
            QMessageBox::warning(this,"","学工号不能为空!");
        else
            if(password == "")
                QMessageBox::warning(this,"","密码不能为空!");
            else{
                bool flag = updateadmin(db,userid, password);
                if(flag){
                    QMessageBox::information(this,"","密码修改成功!");
                    
                }else
                    QMessageBox::warning(this,"","学工号信息不匹配!");
            }
    }else if(flag1 == 1){
        if(QString::number(userid) == "")
            QMessageBox::warning(this,"","学工号不能为空!");
        else
            if(password == "")
                QMessageBox::warning(this,"","密码不能为空!");
            else{
                bool flag = updateteach(db,userid, password);
                if(flag){
                    QMessageBox::information(this,"","密码修改成功!");
                    
                }else
                    QMessageBox::warning(this,"","学工号信息不匹配!");
            }
    }else if(flag1 == 2){
        if(QString::number(userid) == "")
            QMessageBox::warning(this,"","学工号不能为空!");
        else
            if(password == "")
                QMessageBox::warning(this,"","密码不能为空!");
            else{
                bool flag = updatestud(db,userid, password);
                if(flag){
                    QMessageBox::information(this,"","密码修改成功!");
                    
                }else
                    QMessageBox::warning(this,"","学工号信息不匹配!");
            }
    }
}

相关函数:

// 更新数据(修改数据)
bool re_pwd::updatestud(QSqlDatabase db, const int &userid, const QString &password)
{
    QSqlQuery query(db);
    query.prepare("UPDATE admin SET password=:password WHERE id=:id");
    query.bindValue(":id", userid);
    query.bindValue(":password",password);
    query.exec();
}

登录(login)

老师和管理员登录:判断id输入的长度,然后到相应数据库表里面检索,若成功则跳转对应页面(3个if语句)。用getLastWindow函数(注册页面里面也用了)将对应的名字显示到下一个页面里(这里用学生登录里面的ini文件一样实现,并且更简单)

学生登录:通过ini配置文件的读写, 每次登录的时候通过输入的id号查找数据库,再将数据库里面数据写入配置文件,新页面加载后对配置文件进行读取,实现两个页面对应数据传递
// 因为登录后有修改信息的步骤,需要一个ini作为过渡文件方便检测是谁在登录,这是后面写到这一步的时候出现的问题,以至于和前面老师和管理员的写法不同

请添加图片描述

管理员页面 (admin) 增删改查

显示表格:tableWidget
对表格clear(防止重复出现和删除不掉)然后从对应表格中SELECT 全部(分别对学生,老师,实验室建了3个检索函数)
通过CountRowTch函数查找对应表行数的,通过对tableWidget 填入数据之前先setRowCount(设置行数)来实现每次表格长度根据被查表格总数据数量进行自动增长

请添加图片描述
建学生表(老师和实验室类似)

// 建表
ui->stackedWidget->setCurrentIndex(0);

    //学生表
    ui->tableWidget->setRowCount(10);//设置行数
    ui->tableWidget->setColumnCount(3);//设置列数
    ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"学号"<< "姓名"<< "密码");//设置表头
    ui->tableWidget->setColumnWidth(0,130);//设置列宽
    ui->tableWidget->setColumnWidth(1,130);
    ui->tableWidget->setColumnWidth(2,130);
    ui->tableWidget->setColumnWidth(3,70);
    ui->tableWidget->setColumnWidth(4,70);
    ui->tableWidget->setColumnWidth(5,70);
    ui->tableWidget->setColumnWidth(6,70);


    //隔行变色
    ui->tableWidget->setAlternatingRowColors(true);

    //设置全部单元格可编辑
    ui->tableWidget->setEditTriggers(QAbstractItemView::DoubleClicked);

    //表格横向自适应
    ui->tableWidget->horizontalHeader()->setSectionResizeMode((QHeaderView::Stretch));

将数据显示在表格中

// 显示数据
void admin::FindStu()
{
    ui->tableWidget->clear();
    ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"学号"<< "姓名"<< "密码");//设置表头
    QSqlQuery query;
    query.exec("SELECT * FROM student ORDER BY id ASC");  //data 为表名  10代表获取10条数据

    int t_rowCount = CountRowStu();
    ui->tableWidget->setRowCount(t_rowCount+3);

    for(int i=0;i<10;i++)
    {
        query.next();
        QString id = query.value("id").toString();
        QString name = query.value("name").toString();
        QString password = query.value("password").toString();

        int j=0;
        ui->tableWidget->setItem(i,j, new QTableWidgetItem(id));//第i行第j列
        j++;
        ui->tableWidget->setItem(i,j, new QTableWidgetItem(name));
        j++;
        ui->tableWidget->setItem(i,j, new QTableWidgetItem(password));
        j++;
    }
}

增:
将id和name两个输入框的值保留,进行if判断:若password为空则设置默认密码123456.不为空将输入的值保留,最后将3个值一起insert插入表格

请添加图片描述
新增数据

// 新增数据
void admin::on_pbt_insertTch_clicked()
{
    QSqlQuery query;
    int id = ui->Edit_idtch->text().toInt();
    QString name = ui->Edit_nametch->text();
    int role = 1;
    if(ui->Edit_pwdtch->text().isEmpty())
    {
        QString pwd = QString("123456");
        QString sqlInert = QString("INSERT INTO teacher(id,name,password,role) VALUES (%1,'%2','%3',%4);").arg(id)
                .arg(name)
                .arg(pwd)
                .arg(role);
        query.exec(sqlInert);
    }
    else
    {
        QString pwd = ui->Edit_pwdtch->text();
        QString sqlInert = QString("INSERT INTO teacher(id,name,password,role) VALUES (%1,'%2','%3',%4);").arg(id)
                .arg(name)
                .arg(pwd)
                .arg(role);
        query.exec(sqlInert);
    }
    FindTch();
}

删:
对学工号进行查找,查找到后在数据库中delete删除,最后刷新一下显示的表

请添加图片描述

// 删除数据
void admin::on_pbt_deleteTch_clicked()
{
    QSqlQuery query;
    int id = ui->Edit_idtch->text().toInt();
    if(ui->Edit_idtch->text().isEmpty())
    {
        QMessageBox::warning(this,"","请输入要删除的学工号");

    }
    else
    {
        QString sqlDel = QString("DELETE FROM teacher WHERE id =%1").arg(id);
        query.exec(sqlDel);
    }
    FindTch();
}

改:
通过对3个输入框分别检索,由2个if判断对password和name进行分别更改 ,输入为空默认该值不改

请添加图片描述

// 修改数据
void admin::on_pbt_changeTch_clicked()
{
    QSqlQuery query;
    int id = ui->Edit_idtch->text().toInt();
    QString name = ui->Edit_nametch->text();
    QString pwd = ui->Edit_pwdtch->text();

    if(ui->Edit_idtch->text().isEmpty())
    {
        QMessageBox::warning(this,"","请输入要操作的学工号");
    }
    else
    {
        if(ui->Edit_pwdtch->text().isEmpty())
        {
        }
        else
        {
            QString sqlUpd = QString("UPDATE teacher SET password = '%1' WHERE id = %2 ").arg(pwd).arg(id);
            query.exec(sqlUpd);
        }
        if(ui->Edit_nametch->text().isEmpty())
        {
        }
        else
        {
            QString sqlUpd = QString("UPDATE teacher SET name = '%1' WHERE id = %2 ").arg(name).arg(id);
            query.exec(sqlUpd);
        }
    }
    FindTch();
}

查:
设置一个列表和一个指向QTableWidgetItem的指针,然后将输入的学工号传给该指针,然后获取指针的所在行,进行滑动条定位,最后将这一行设置为选中

参考: 查找并定位到指定行
请添加图片描述

// 查找指定行
void admin::on_pbt_findStu_clicked()
{

    if(ui->Edit_idstu->text().isEmpty() )
    {
        return;
    }
    //一个列表和一个指向QTableWidgetItem的指针 主打一个看不懂
    QList<QTableWidgetItem *>   items;
    QTableWidgetItem            *item;

    items  = ui->tableWidget->findItems(ui->Edit_idstu->text(), Qt::MatchExactly);//在表格中查找数据项

    //找到了这个数据项
    if(items.length() > 0)
    {
        item = items[0];//获取到数据项
        int r = item->row();//获取所在行
        ui->tableWidget->verticalScrollBar()->setSliderPosition(r);//滚动条定位到数据所在位置
        ui->tableWidget->setCurrentItem(item);//将这个数据所在行设置为表格的当前行

        ui->tableWidget->selectRow(r);

    }
}

学生页面 (student)

修改个人信息

1.需要读取登录人数据,利用ini配置文件,将登录时候的账号存入ini文件,然后在学生页面修改时直接读取ini里面存好的账号,改动其数据库信息
2.修改信息利用UPDATE语句

请添加图片描述
完善个人信息

// 完善个人信息
void student::on_pbt_sureStu_clicked()
{
    ui->stackedWidget->setCurrentIndex(1);
    QString name = ui->Edit_namestu->text(); //保存编辑框内的输入信息
    QString inst = ui->Edit_inststu->text();
    QString pwd = ui->Edit_pwdstu->text();
    QSettings settings("login.ini",QSettings::IniFormat); //利用配置文件查找id(3行)
    settings.setIniCodec(QTextCodec::codecForName("UTF8"));
    QString id = settings.value("/nowbegin/id").toString();
    QSqlQuery query(db);
    if(ui->Edit_pwdstu->text().isEmpty()) //非空才修改
    {}
    else
    {
        QString sqlUpd = QString("UPDATE student SET password = '%1' WHERE id = %2 ").arg(pwd).arg(id.toInt());  //更新数据库里面内容
        query.exec(sqlUpd);

    }
    if(ui->Edit_namestu->text().isEmpty())
    {}
    else
    {
        QString sqlUpd = QString("UPDATE student SET name = '%1' WHERE id = %2 ").arg(name).arg(id.toInt());//更新数据库里面内容
        query.exec(sqlUpd);
    }
    if(ui->Edit_inststu->text().isEmpty())
    {}
    else
    {
        QString sqlUpd = QString("UPDATE student SET institute = '%1' WHERE id = %2 ").arg(inst).arg(id.toInt());//更新数据库里面内容
        query.exec(sqlUpd);
    }

    changeInformationInini(id.toInt());//将数据库内容修改到ini配置文件
    readInformationInini();//将ini文件里面内容显示到页面
}

void student::changeInformationInini(int id)  //将数据库内容修改到ini配置文件
{
    QSqlQuery query(db);
    query.prepare("SELECT id,name,institute,role,labid FROM student WHERE id = :id;");
    query.bindValue(":id",id);
    if(query.exec()&&query.next())
    {
        QSettings settings("login.ini",QSettings::IniFormat);
        settings.setIniCodec(QTextCodec::codecForName("UTF8"));

        settings.setValue("/nowbegin/id",query.value(0).toString());
        settings.setValue("/nowbegin/name",query.value(1).toString());
        settings.setValue("/nowbegin/inst",query.value(2).toString());
        settings.setValue("/nowbegin/flag",query.value(3).toString());
        settings.setValue("/nowbegin/labid",query.value(4).toString());
    }
}

void student::readInformationInini()  //将ini文件里面内容显示到页面
{
    QSettings settings("login.ini",QSettings::IniFormat);
    settings.setIniCodec(QTextCodec::codecForName("UTF8"));
    QString id = settings.value("/nowbegin/id").toString();
    QString name = settings.value("/nowbegin/name").toString();
    QString inst = settings.value("/nowbegin/inst").toString();
    QString labid = settings.value("/nowbegin/labid").toString();

    QString str =QString("欢迎您,%1(学生)").arg(name);
    ui->label_id->setText(str);
    ui->label_id->adjustSize();

    ui->label_name->setText(name);
    ui->label_id_2->setText(id);
    ui->label_inst->setText(inst);
    ui->label_lab->setText(labid);
    ui->label_lab_2->setText(labid);

}
实验室功能

1.预约:新建一个实验室表,设置总数total和已经预约人数num,在按下预约按钮时进行判断人数是否超过总数,没有超过则num+1
2.为了保证一个学生不重复预约多个实验室,设置每次预约前检测对应的labid里面是否有值,若有值返回0不予预约
3.取消预约的时候将该学生的labid清空,并将对应的实验室num-1

请添加图片描述

// 预约功能
bool student::addLabNum(int id) //实验室可预约人数加一
{
    QSqlQuery query(db);
    query.prepare("SELECT total,num FROM lab WHERE id = :id;");
    query.bindValue(":id",id);
    if(query.exec()&&query.next())
    {
        int labtotal = query.value(0).toInt(); //读取总人数和可预约人数
        int labnum = query.value(1).toInt();
        if(labtotal>labnum)   //总人数大于当前预约人数才进行预约(加一)
        {
            QString sqladd = QString("UPDATE lab SET num = num+1 WHERE id = %1 ").arg(id);
            query.exec(sqladd);
            return 1;
        }
        else return 0;
    }
}

bool student::minuLabNum(int id)  //实验室可预约人数减一
{
    QSqlQuery query(db);
    query.prepare("SELECT total,num FROM lab WHERE id = :id;");
    query.bindValue(":id",id);
    if(query.exec()&&query.next())
    {
        //int labtotal = query.value(0).toInt();
        int labnum = query.value(1).toInt();
        if(labnum)
        {
            QString sqlminu = QString("UPDATE lab SET num = num-1 WHERE id = %1 ").arg(id);
            query.exec(sqlminu);
            return 1;
        }
        else return 0;
    }
}

void student::on_pbt_cancelLab_clicked()  //取消预约
{
    QString labid = ui->label_lab_2->text();
    if(labid != NULL) //非空才进入minuLabNum函数
    {
        int flag =minuLabNum(labid.toInt());
        if(flag)
        {
            QSettings settings("login.ini",QSettings::IniFormat);
            settings.setIniCodec(QTextCodec::codecForName("UTF8"));
            QString id = settings.value("/nowbegin/id").toString();

            QSqlQuery query(db);
            QString sqlLabid = QString("UPDATE student SET labid = NULL WHERE id = %1 ")
                    .arg(id);
            query.exec(sqlLabid);
            changeInformationInini(id.toInt());
            readInformationInini();
        }
        else QMessageBox::warning(this,"","取消预约失败");
    }else QMessageBox::warning(this,"","请先预约!");
    FindLab();
}

void student::on_pbt_orderLab_clicked()  //确认预约按钮
{

    QString labidNow = ui->label_lab_2->text();
    QString labidNew = ui->Edit_idLab->text();

    if(labidNow == NULL) //当前预约为空才进入下一步
    {
        int flag =addLabNum(labidNew.toInt());
        if(flag)
        { //预约成功后更新ini文件
            QSettings settings("login.ini",QSettings::IniFormat);
            settings.setIniCodec(QTextCodec::codecForName("UTF8"));
            QString id = settings.value("/nowbegin/id").toString();

            QSqlQuery query(db);
            QString sqlLabid = QString("UPDATE student SET labid = %1 WHERE id = %2 ")
                    .arg(labidNew)
                    .arg(id);
            query.exec(sqlLabid);
            changeInformationInini(id.toInt());
            readInformationInini();
        }
        else QMessageBox::warning(this,"","该实验室预约人数已满!");
    }else{
        QMessageBox::warning(this,"","请先取消预约!");
    }

    FindLab();  //刷新表格

}

老师页面 (teacher)

没写什么东西,利用label放了图片qwq

请添加图片描述

// 播放图片
    QMovie *movie = new QMovie(":/image/emoji/pray.gif");
    ui->label_2->setMovie(movie);
    movie->start();

工程文件下载

工程文件: 基于Qt的实验室管理系统的设计(作业)

  • 41
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值