【qt】考试系统项目

news2024/11/11 10:08:26

话不多说,先一睹芳颜
在这里插入图片描述

咱们的账号,题库和答案都是通过文件获取的.
话不多说,直接开干

目录

  • 一.登录窗口
    • 1.界面设计
    • 2.邮箱验证
    • 3.登录验证
  • 二.题库窗口
    • 1.考试计时
    • 2.布局管理器
    • 3.题库显示
    • 4.按钮布局
    • 5.计算分数
  • 三.窗口交互
  • 四.完整代码
  • 五.结语

一.登录窗口

1.界面设计

在这里插入图片描述
在这里插入图片描述
这里添加背景图片.
在这里插入图片描述
密码输入模式和提示语句.
在这里插入图片描述

注意:背景图标放在的标签必须要第一个,不然会盖住其他组件.

2.邮箱验证

在这里插入图片描述

用正则表达式来进行判断.

3.登录验证

在这里插入图片描述
第一行读取的话,要跳过,我们不用.
在这里插入图片描述
中间有多个空格,所以我们可以使用正则表达式来进行匹配来获取子串.

在这里插入图片描述
如果循环完都没有找到就说明我们输入的账号有问题,所以这个是循环读取外面加的.

二.题库窗口

1.考试计时

需要用到计时器
在这里插入图片描述
每隔一秒,我们就发出timeout()这个信号.
在这里插入图片描述
然后计算分秒来设置在窗口的标题上.

在这里插入图片描述
对窗口进行一点的渲染.

2.布局管理器

这是一个神器,当我们用代码来写组件的时候,有了它,你可以高枕无忧的布局.
在这里插入图片描述
下面我们布局组件的时候可以来看布局管理器怎么使用.

3.题库显示

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
定义了这个来保存我们的答案,方便我们后面计算分数.

在这里插入图片描述
添加到组件上,并使用布局管理器.
第一个参数是要添加布局的组件
第二三个参数是这个组件的位置,可以把布局管理器理解成一个表格,从0行0列开始
第四五哥参数是这个组件所占的行数和列数.

4.按钮布局

在这里插入图片描述
用的组件数组来初始化.

在这里插入图片描述
在这里插入图片描述
初始化单选题的时候,我们要进行分组,这样才可以每个题选一项.
同时添加到布局管理器中.

在这里插入图片描述
初始化按钮并关联槽函数,来计算分数.

5.计算分数

在这里插入图片描述
在计算分数前,我们先来判断是否所有的题都已答完,若没有就继续.
在这里插入图片描述
单选题只需要判断每个单选组里面有没有选择的即可.
多选题记一下数,看是不是大于等于2即可

接下来就是正式的算分了.
多选题的算分比较复杂
在这里插入图片描述
先获取答案中有那些选项,我们用bool类型来设置状态.
然后与多选框的每个选项状态一一对比.
完全一样才得分.

在这里插入图片描述
单选题和判断题都从按钮组中获取到文本来与我们先前获取到的答案进行对比.
在这里插入图片描述
显示分数,并给用户选择是否重新答题.

三.窗口交互

现在,我们的两个窗口都写好了,怎么衔接起来呢?
在这里插入图片描述
在这里插入图片描述
这个可以关闭当前的窗口,并返回一种用户点击的信息.

在这里插入图片描述
在main中用模态的方式,来进行接受信息.
并构造我们的考试窗口.
在考试窗口的构造函数中进行显示,以防未初始化窗口就进行显示.
在这里插入图片描述

四.完整代码

examdialog.h

#ifndef EXAMDIALOG_H
#define EXAMDIALOG_H
#include <QDialog>
#include <QTimer>
#include <QGridLayout>
#include <QTextEdit>
#include <QRadioButton>
#include <QCheckBox>
#include <QPushButton>
#include <QLabel>
#include <QButtonGroup>

class ExamDialog : public QDialog
{
    Q_OBJECT
public:
    ExamDialog(QWidget *parent=0);
    void initTimer();
    void initLayout();
    bool initTextEdit();
    void initButton();
    bool hasSelected();
    void getScores();

private:
    QTimer*m_timer;
    int m_sec=0;
    QGridLayout*m_layout;
    QTextEdit*m_textEdit;
    QLabel*m_label[10];
    QRadioButton*m_radioBtn[32];
    QRadioButton*m_radioA;
    QRadioButton*m_radioB;
    QCheckBox*m_CheckBoxBtn[4];
    QStringList answers;
    QButtonGroup*BtnGroup[9];


private slots:
    void onTimeout();
    void onBtn();
};

#endif // EXAMDIALOG_H

examdialog.cpp

#include "examdialog.h"
#include <QApplication>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>

ExamDialog::ExamDialog(QWidget *parent):QDialog(parent)
{
    resize(800,900);
    this->setWindowTitle("已考试: 0分0秒");
    QFont font;
    font.setPointSize(20);
    this->setFont(font);
    setPalette(QPalette(QColor(213,81,213)));
    setWindowFlags(Qt::Dialog|Qt::WindowCloseButtonHint);

    initTimer();
    initLayout();
    if(!initTextEdit())
    {
        QTimer::singleShot(0,qApp,SLOT(quit()));
    }
    initButton();
    show();//都初始化成功,我才显示.
}

void ExamDialog::initTimer()
{
    m_timer=new QTimer(this);
    m_timer->setInterval(1000);
    m_timer->start();
    connect(m_timer,SIGNAL(timeout()),this,SLOT(onTimeout()));
}

void ExamDialog::initLayout()
{
    m_layout=new QGridLayout(this);
    m_layout->setSpacing(10);
    m_layout->setMargin(10);
}

bool ExamDialog::initTextEdit()
{
    m_textEdit=new QTextEdit(this);
    m_textEdit->setReadOnly(true);

    QString fileName="../tk.txt";
    QFile file(fileName);
    QTextStream stream(&file);
    stream.setCodec("UTF-8");

    if(!file.open(QIODevice::ReadOnly|QIODevice::Text))return false;

    QString line;
    QStringList list;
    QString passage;
    int nline=0;

    while (!stream.atEnd())
    {
        if(nline==0)
        {
            stream.readLine();
            nline++;
            continue;
        }
        if((nline>=6&&nline<=6*9&&(nline%6==0))||(nline==6*9+4))
        {
            line=stream.readLine();
            list=line.split(" ");
            answers.append(list.at(1));//服了
            passage+="\n";
            nline++;
            continue;
        }
        line=stream.readLine();
        passage+=line;
        passage+="\n";
        nline++;
    }
    m_textEdit->setText(passage);
    m_layout->addWidget(m_textEdit,0,0,1,10);
    file.close();
    return true;
}

void ExamDialog::initButton()
{
    QStringList chooseList={"A","B","C","D"};
    for(int i=0;i<10;i++)
    {
        m_label[i]=new QLabel(this);
        m_label[i]->setText("第"+QString::number(i+1)+"题");
        m_layout->addWidget(m_label[i],1,i);

        if(i==8)
        {
            for(int j=0;j<4;j++)
            {
                m_CheckBoxBtn[j]=new QCheckBox(this);
                m_CheckBoxBtn[j]->setText(chooseList[j]);
                m_layout->addWidget(m_CheckBoxBtn[j],j+2,i);
            }
            continue;
        }
        if(i==9)
        {
            m_radioA=new QRadioButton(this);
            m_radioA->setText("对");
            m_radioB=new QRadioButton(this);
            m_radioB->setText("错");
            BtnGroup[8]=new QButtonGroup(this);
            BtnGroup[8]->addButton(m_radioA);
            BtnGroup[8]->addButton(m_radioB);
            m_layout->addWidget(m_radioA,2,i);
            m_layout->addWidget(m_radioB,3,i);
            continue;
        }

        BtnGroup[i]=new QButtonGroup(this);

        for(int j=0;j<4;j++)
        {
            m_radioBtn[i*4+j]=new QRadioButton(this);
            m_radioBtn[i*4+j]->setText(chooseList[j]);
            BtnGroup[i]->addButton(m_radioBtn[i*4+j]);
            m_layout->addWidget(m_radioBtn[i*4+j],2+j,i);
        }
    }
    QPushButton *Btn=new QPushButton(this);
    Btn->setText("提交");
    m_layout->addWidget(Btn,6,9);
    connect(Btn,SIGNAL(clicked()),this,SLOT(onBtn()));
}

bool ExamDialog::hasSelected()
{
    int checkCount=0;
    for(int j=0;j<4;j++)
    {
        if(m_CheckBoxBtn[j]->isChecked())
        {
            checkCount++;
        }
    }
    if(checkCount==0||checkCount==1)
    {
        return false;
    }

    for(int i=0;i<9;i++)
    {
        if(!BtnGroup[i]->checkedButton())
        {
            return false;
        }
    }
    return true;

}

void ExamDialog::getScores()
{
    int score=0;
    for(int i=0;i<10;i++)
    {
        if(i==8)
        {
            QString answer=answers.at(i);
            bool hasA=false;
            bool hasB=false;
            bool hasC=false;
            bool hasD=false;
            if(answer.contains("A")) hasA=true;
            if(answer.contains("B")) hasB=true;
            if(answer.contains("C")) hasC=true;
            if(answer.contains("D")) hasD=true;

            if(m_CheckBoxBtn[0]->isChecked()==hasA&&
               m_CheckBoxBtn[1]->isChecked()==hasB&&
               m_CheckBoxBtn[2]->isChecked()==hasC&&
               m_CheckBoxBtn[3]->isChecked()==hasD)
            {
                score+=10;
            }
            continue;
        }
        if(i==9)
        {
            QString answer=answers.at(i);
            if(BtnGroup[8]->checkedButton()->text()==answer)
            {
                score+=10;
            }
            continue;
        }

        if(BtnGroup[i]->checkedButton()->text()==answers[i])
        {
            score+=10;
        }
    }

    int res=QMessageBox::information(this,"提示","您的考试分数为:"+QString::number(score)+"分,是否需要重新考试?",
                             QMessageBox::Yes|QMessageBox::No);
    if(res==QMessageBox::Yes)
    {
        return;
    }
    else
    {
        close();
    }
}


void ExamDialog::onTimeout()
{
    m_sec++;
    int minute=m_sec/60;
    int sec=m_sec%60;
    this->setWindowTitle("已考试: "+QString::number(minute)+"分"+QString::number(sec)+"秒");
}

void ExamDialog::onBtn()
{
    if(!hasSelected())
    {
        QMessageBox::information(this,"提示","题没作答完,请继续作答!");
    }
    else
    {
        getScores();
    }
}

logindialog.h

#ifndef LOGINDIALOG_H
#define LOGINDIALOG_H

#include <QDialog>

QT_BEGIN_NAMESPACE
namespace Ui { class loginDialog; }
QT_END_NAMESPACE

class loginDialog : public QDialog
{
    Q_OBJECT

public:
    loginDialog(QWidget *parent = nullptr);
    ~loginDialog();

private slots:
    void on_pushButtonLogin_clicked();

    void on_pushButtonCancel_clicked();

private:
    Ui::loginDialog *ui;


    void loginFromFile();
};
#endif // LOGINDIALOG_H

logindialog.cpp

#include "logindialog.h"
#include "ui_logindialog.h"
#include <QMessageBox>
#include <QFile>
#include <QTextStream>
#include <QDebug>

loginDialog::loginDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::loginDialog)
{
    ui->setupUi(this);
    ui->label->setScaledContents(true);
    resize(ui->label->width(),ui->label->height());
    setFixedSize(ui->label->width(),ui->label->height());
    setWindowFlags(Qt::Dialog|Qt::WindowCloseButtonHint);
    setWindowTitle("考试系统");
}

loginDialog::~loginDialog()
{
    delete ui;
}


void loginDialog::on_pushButtonLogin_clicked()
{
    QRegExp reg("^[A-Za-z0-9]+(_[A-Za-z0-9]+)*@[A-Za-z0-9]+(_[A-Za-z0-9]+)*\.[A-Za-z]{2,6}$");
    bool res=reg.exactMatch(ui->lineEditAccount->text());
    if(res)
    {
        loginFromFile();
    }
    else
    {
        QMessageBox::information(this,"提示","邮箱格式有误,请重新输入!");
        ui->lineEditPWD->clear();
        ui->lineEditAccount->clear();
        ui->lineEditAccount->setFocus();
        return;
    }
}

void loginDialog::loginFromFile()
{
    QString line;
    QString account;
    QString pwd;
    QStringList list;
    int nline=0;

    account=ui->lineEditAccount->text();
    pwd=ui->lineEditPWD->text();

    QString fileName("../account.txt");
    QFile file(fileName);
    QTextStream stream(&file);
    if(!file.open(QIODevice::ReadOnly|QIODevice::Text))return;
    while(!stream.atEnd())
    {
        if(nline==0)
        {
            stream.readLine();
            nline++;
            continue;
        }
        line=stream.readLine();
        QRegExp reg("\\s+");
        list=line.trimmed().split(reg);
        nline++;
        if(account==list.at(0))
        {
            if(pwd==list.at(1))
            {
                QMessageBox::information(this,"提示","登录成功,欢迎进入考试系统!");
                file.close();
                done(Accepted);
                return;
            }
            else
            {
                QMessageBox::information(this,"提示","密码输入有误,请重新输入!");
                ui->lineEditPWD->clear();
                ui->lineEditPWD->setFocus();
                file.close();
                return;
            }
        }
    }

    QMessageBox::information(this,"提示","账户输入有误,请重新输入!");
    ui->lineEditAccount->clear();
    ui->lineEditPWD->clear();
    ui->lineEditAccount->setFocus();
    file.close();
    return;
}

void loginDialog::on_pushButtonCancel_clicked()
{
    done(Rejected);
}

main.cpp

#include "logindialog.h"

#include <QApplication>
#include "examdialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    loginDialog w;
    int res=w.exec();
    if(res==QDialog::Accepted)
    {
        ExamDialog *examDialog=new ExamDialog;        
    }
    else
    {
        return 0;
    }

    return a.exec();
}

五.结语

当然这个读取文件没有自适应,需要根据你的文件内容进行调整.
完结撒花.

好想到筑基期呀.君子生非异也,善假于物也.

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

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

相关文章

跟着操作,解决iPhone怎么清理内存难题

在如今智能手机功能日益强大的时代&#xff0c;我们使用手机拍照、录制视频、下载应用、存储文件等操作都会占用手机内存。当内存空间不足时&#xff0c;手机运行会变得缓慢&#xff0c;甚至出现卡顿、闪退等现象。因此&#xff0c;定期清理iPhone内存是非常必要的。那么&#…

人工智能与专家系统:构建智慧决策的未来

引言 随着信息技术的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经成为当今科技领域的一个重要分支&#xff0c;并在多个行业中展现出了巨大的潜力和影响力。人工智能通过模拟人类的智能行为&#xff0c;使计算机能够执行诸如学习、推理、解决问题和理解自然语言…

vite-服务端渲染(ssr)项目线上频繁刷新(踩坑记录)

今天来分享一个我在公司修改之前前端留下来的项目的坑。来说说大致的一个经过把&#xff0c;我老板说这个项目是之前的一个前端做的&#xff0c;用的是ssr服务端渲染的技术&#xff0c;不过他项目在线上会一直频繁的刷新&#xff0c;据说他想破脑袋都想不出来&#xff0c;最终因…

周鸿祎为什么建议Java、前端、大数据、PHP开发都要学一下大模型?_ai大模型全栈工程师跟java有关吗

ChatGPT的出现在全球掀起了AI大模型的浪潮&#xff0c;2023年可以被称为AI元年&#xff0c;AI大模型以一种野蛮的方式&#xff0c;闯入你我的生活之中。 从问答对话到辅助编程&#xff0c;从图画解析到自主创作&#xff0c;AI所展现出来的能力&#xff0c;超出了多数人的预料&…

【企业级监控】Zabbix监控网站并发连接数

Zabbix自定义监控项与触发器 文章目录 Zabbix自定义监控项与触发器资源列表基础环境前言一、什么是zabbix的Key值二、获取远程Key值2.1、获得主机的Key值2.2、被监控端安装Agent2.3、zabbix_get命令获取Agent数据举例2.3.1、zabbx_get获取cpu核心数2.3.2、获取目标主机系统和内…

windows中超详细深度学习环境配置之安装显卡驱动、cuda、cudnn、pytorch、torchvision、pycharm

超详细介绍安装Gpu版本的pytorch深度学习环境 一、显卡驱动安装1.1 下载驱动1.2 安装驱动 二、cuda安装2.1 下载cuda2.2 安装cuda2.3 检查cuda是否安装成功 三、安装cudnn3.1 cudnn下载3.2 cudnn安装 四、安装miniconda4.1 miniconda下载4.2 miniconda安装4.3 添加环境变量 五、…

数字营销以打造“会员体系”为主要目标的好处和优势

​蚓链数字化营销实践观察&#xff1a;在数字化时代&#xff0c;企业的营销方式发生了深刻的变革。会员体系作为一种常见的营销策略&#xff0c;在数字营销领域中发挥着越来越重要的作用。 首先&#xff0c;我们来总结一下会员体系的特点和优势 &#xff08;一&#xff09;个性…

图注意力网络

【图书推荐】《图神经网络基础、模型与应用实战》_搭建神经网络需要看什么书-CSDN博客 图注意力网络的由来和发展 图注意力网络&#xff08;GAT&#xff09;是一种图神经网络&#xff08;GNN&#xff09;模型&#xff0c;最早由Petar Velickovic等在2017年提出。它的设计灵感…

Java基础-I/O流

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 字节流 定义 说明 InputStream与OutputStream示意图 说明 InputStream的常用方法 说明 OutputStrea…

Qt基础 | Qt Creator的基本介绍与使用 | 在Visual Studio中创建Qt项目

文章目录 一、Qt Creator的基本介绍与使用1.新建一个项目2.项目的文件组成3.项目文件介绍3.1 项目管理文件3.2 界面文件3.3 主函数文件3.4 窗体相关的文件 4.项目的编译、调试与运行 二、在Visual Studio中创建Qt项目 Qt C开发环境的安装&#xff0c;请参考https://liujie.blog…

C1W1.LAB.Preprocessing+Word frequencies+Logistic_regression_model

理论课&#xff1a;C1W1.Sentiment Analysis with Logistic Regression 文章目录 预处理导入包Twitter dataset简介查看原始文本处理原始文本处理超链接、Twitter 标记和样式分词去除标点和停用词词干处理 process_tweet() 词频构建与可视化导入包加载数据集字典字典实例添加或…

cesium 实现地图环境功能 - 雨,雪,雾特效

需求背景解决效果Codeindex.vuefogEffect.tsrain.glslsnow.glslfog.glsl 需求背景 需要实现天气模拟&#xff0c;日照模拟功能&#xff0c;提高三维实景效果 解决效果 Code 注意&#xff1a;我以下glsl文件时基于 webgl1.0&#xff0c;即cesium&#xff0c;创建球的时候&…

ES的使用示例

1.安装 ES的安装对springboot的版本配置要求很高&#xff0c;需要根据如下的目录下载对应的版本。 查看自己项目所使用的springboot和spring的版本&#xff0c;对应下载文件。 下载链接地址&#xff1a;https://www.elastic.co/cn/downloads/past-releases/elasticsearch-7-…

微软GraphRAG原理介绍(附带部分源码)

我们前几天写了一篇文章&#xff0c;简单跑了一下GraphRAG看了下效果&#xff0c;没看过这篇文章的可以看下https://www.luxinfeng.top/article/动手实操微软开源的GraphRAG。今天我们介绍一下GraphRAG的实现原理&#xff0c;关于实验对比的内容&#xff0c;我会在下一篇文章中…

48V电源架构解析

48V电源架构解析 48V系统的诞生 汽车在1918年引入蓄电池&#xff0c;到1920年逐渐普及&#xff0c;当时的电池电压是6V。后来&#xff0c;随着内燃机排量的增加以及高压缩比内燃机的出现&#xff0c;6V系统已经不能满足需求&#xff0c;于是在1950年引入了12V系统。大多数汽车…

【python学习】标准库之数学相关math库的定义、功能、使用场景、代码示例和第三方数学相关库NumPy

引言 math模块是Python标准库的一部分&#xff0c;它提供了一系列基本的数学函数和常数。这些函数和常数对于日常的数学运算非常有用&#xff0c;例如计算平方根、计算余弦值等。 文章目录 引言一、math的定义二、math的功能2.1 基本的数学运算2.2 数学常数2.3 随机数 三、math…

八臂-聚乙二醇-生物素;8ARM-PEG-Biotin

一、基本信息 名称&#xff1a;八臂PEG生物素、八臂-聚乙二醇-生物素、Octa-arm PEG Biotin、8ARM-PEG-Biotin 结构&#xff1a;具有八个分支的PEG链&#xff0c;每个分支末端连接生物素分子 状态&#xff1a;固体/粉末/溶液&#xff0c;具体取决于产品规格和存储条件 纯度&…

论文去AI痕秘籍:轻松几步,守护你的学术原创性

如何有效降低AIGC论文的重复率&#xff0c;也就是我们说的aigc如何降重&#xff1f;AIGC疑似度过高确实是个比较愁人的问题。如果你用AI帮忙写了论文&#xff0c;就一定要在交稿之前做一下AIGC降重的检查。一般来说&#xff0c;如果论文的AIGC超过30%&#xff0c;很可能会被判定…

Qt|QTreewidget类下函数qt助手详解说明示例(二)

上篇&#xff1a;Qt|QTreewidget类下函数qt助手详解说明示例&#xff08;一&#xff09; 该系列持续更新&#xff0c;喜欢请一键三连&#xff0c;一起学习进步&#xff0c;升职加薪&#xff0c;感谢各位大佬。 QT5.14.2 参考官方QT助手 Kimi辅助说明 文章目录 insertTopLevelI…

浅学三次握手

数据要完成传输&#xff0c;必须要建立连接。由于建立TCP连接的过程需要来回3次&#xff0c;所以&#xff0c;将这个过程形象的叫做三次握手。 结合上面的图来看更清楚。 先说三次握手吧&#xff0c;连接是后续数据传输的基础。就像我们打电话一样&#xff0c;必须保证我和对方…