Qt 科目一考试系统(有源码)

news2024/11/26 10:23:15

项目源码和资源:科目一考试系统: qt实现科目一考试系统

 一.项目概述

该项目是一个基于Qt框架开发的在线考试系统,主要实现了考试题目的随机抽取、考试时间限制、成绩统计等功能。用户可以通过界面操作进行考试,并查看自己的考试成绩。
 

二.技术栈

Qt框架、C++语言、GUI设计、数据结构、算法等。

三.界面展示

1.登录界面

2.答题界面

3.提交界面

四.代码展示

1.核心要点

整体项目共分为两个部分,登录界面和答题界面,登录界面使用的qt设计器进行手动设计,登录界面核心的点在于使用正则表达式对已有账号进行分析,答题界面核心则是对文件中的试题进行处理。

 2.登录界面代码

#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_pushButtonOk_clicked();

    void on_pushButtonCancel_clicked();

private:
    Ui::LoginDialog *ui;

private:
    void InitUI();
};
#endif // LOGINDIALOG_H
#include "logindialog.h"
#include "ui_logindialog.h"
#include<QIcon>
#include<QMessageBox>
#include<QFile>
#include<QTextStream>

LoginDialog::LoginDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::LoginDialog)
{
    ui->setupUi(this);
    InitUI();
}

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

void LoginDialog::InitUI()
{
    //设置窗口大小
    int wide=ui->labelimage->width();
    int height=ui->labelimage->height();
    this->setGeometry(600,300,wide,height);
    this->setWindowTitle("科目一考试系统");

    this->setWindowFlags(Qt::Dialog|Qt::WindowTitleHint);

}


void LoginDialog::on_pushButtonOk_clicked()
{
    
        QRegExp rx("^[a-zA-Z][\\w]{5,17}@([A-Za-z0-9\\-]+\\.)+[A-Za-z]{2,6}$");

        bool res = rx.exactMatch(ui->lineEditaccount->text());
        if(!res){//匹配不成功
            QMessageBox::information(this,"提示","非法的邮箱地址,请你重新输入!");
            ui->lineEditaccount->clear();
            ui->lineEditpassword->clear();
            ui->lineEditaccount->setFocus();//设置光标
            return;
        }
        else{

            //匹配成功了
            QString filename;   //账号密码数据文件
            QString strAccInput;//用户输入的账号
            QString strCode;    //用户输入的密码
            QString strLine;    //每次读取的一行数据
            QStringList strList;//保存分割读取的一行数据

            filename = "account.txt";//发布时要进行修改
            strAccInput = ui->lineEditaccount->text();//账号
            strCode = ui->lineEditpassword->text();//密码

            QFile file(filename);
            QTextStream stream(&file);
            if( file.open(QIODevice::ReadOnly | QIODevice::Text) )
            {
                while(!stream.atEnd()){
                strLine = stream.readLine();
                strList = strLine.split(",");
                if(strAccInput == strList.at(0))//账号匹配成功
                {
                    if(strCode == strList.at(1)){//密码匹配成功
                        QMessageBox::information(this,"提示","欢迎进入科目一考试系统!");
                        file.close();
                        done(Accepted);
                        return;
                    }else{
                        QMessageBox::information(this,"提示","您输入的密码有误,请重新输入!");
                        ui->lineEditpassword->clear();
                        ui->lineEditpassword->setFocus();
                        file.close();
                        return;
                    }
                }

                QMessageBox::information(this,"提示","您输入的账号有误,请重新输入!");
                ui->lineEditaccount->clear();
                ui->lineEditpassword->clear();
                ui->lineEditaccount->setFocus();
                file.close();
                return;
               }
            }else{
                QMessageBox::information(this,"提示","读取账号数据文件失败!");
                return;
            }
        }

}

void LoginDialog::on_pushButtonCancel_clicked()
{
    //关闭窗口
    this->close();
}

 3.答题界面代码

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

class ExamDialog : public QDialog
{
    Q_OBJECT
public:
    ExamDialog(QWidget* parent = 0);
    void initTimer();   //初始化计时器
    void initLayout();  //初始化布局管理器
    bool initTextEdit();//初始化文本编辑器
    void initButtons(); //初始化按钮及标签
    bool hasNoSelect(); //判断题目是否有未完成的
private:
    QTimer *m_timer;    //计时器
    int m_timeGo;       //考试已用时

    QTextEdit *m_textEdit;  //考试题库显示
    QLabel *m_titleLabels[10];  //题目标签
    QButtonGroup *m_btnGroups[9];   //单项按钮分组
    QRadioButton *m_radioBtns[32];  //单选题按钮
    QCheckBox *m_checkBtns[4];      //多选题按钮
    QRadioButton *m_radioA;         //判断题A选项
    QRadioButton *m_radioB;         //判断题B选项
    QGridLayout *m_layout;          //布局管理器
    QStringList m_answerList;       //答案

private slots:
    void freshTime();   //刷新考试时间
    void getScore();    //获取考试成绩
};

#endif // EXAMDIALOG_H
#include "examdialog.h"
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QApplication>
#include <QPushButton>

ExamDialog::ExamDialog(QWidget* parent):QDialog(parent)
{
    //设置字体大小
    QFont font;
    font.setPointSize(12);
    setFont(font);

    //设置窗体背景颜色
    setPalette(QPalette(QColor(209,215,255)));

    setWindowTitle("考试已用时:0分0秒");
    setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
    resize(800,900);

    initTimer();
    initLayout();
    if(!initTextEdit()){
        QMessageBox::information(this,"提示","初始化题库数据文件失败!");
        QTimer::singleShot(0,qApp,SLOT(quit()));
    }

    initButtons();
    show();
}

void ExamDialog::initTimer()
{
    m_timeGo = 0;
    m_timer = new QTimer(this);
    m_timer->setInterval(1000);
    m_timer->start();

    connect(m_timer,SIGNAL(timeout()),this,SLOT(freshTime()));
}

void ExamDialog::initLayout()
{
    m_layout = new QGridLayout(this);
    m_layout->setSpacing(10);   //设置控件间的间距
    m_layout->setMargin(10);    //设置窗体与控件间的间隙
}

bool ExamDialog::initTextEdit()
{
    QString strLine;        //保存文件中读取到的一行数据
    QStringList strList;    //保存读取到的答案行
    QString fileName("exam.txt");
    QFile file(fileName);
    QTextStream stream(&file);
    stream.setCodec("UTF-8");

    if( file.open(QIODevice::ReadOnly | QIODevice::Text) )
    {
        m_textEdit = new QTextEdit(this);
        m_textEdit->setReadOnly(true);

        QString strText;    //用于保存显示到文本编辑器的数据
        int nLines = 0;
        while(!stream.atEnd()){

            //过滤首行
            if(nLines == 0){
                stream.readLine();
                nLines++;
                continue;
            }

            //过滤答案行
            if( (nLines >= 6 && nLines <= 6 * 9 && (nLines % 6 == 0) )
               || (nLines == 6 * 9 + 4) ){
                strLine = stream.readLine();
                strList = strLine.split(" ");
                m_answerList.append(strList.at(1));
                strText += "\n";
                nLines++;
                continue;
            }

            strText += stream.readLine();
            strText += "\n";
            nLines++;
        }
        m_textEdit->setText(strText);
        m_layout->addWidget(m_textEdit,0,0,1,10);
        file.close();
        return true;
    }else{
        return false;
    }
}

void ExamDialog::initButtons()
{
    QStringList strList = {"A","B","C","D"};
    for(int i = 0; i <10; i++){

        //题目标签
        m_titleLabels[i] = new QLabel(this);
        m_titleLabels[i]->setText("第" + QString::number(i+1) + "题");
        m_layout->addWidget(m_titleLabels[i],1,i);

        //判断题
        if(i == 9){
            m_radioA = new QRadioButton(this);
            m_radioB = new QRadioButton(this);

            m_radioA->setText("正确");
            m_radioB->setText("错误");

            m_layout->addWidget(m_radioA,2,9);
            m_layout->addWidget(m_radioB,3,9);

            m_btnGroups[8] = new QButtonGroup(this);
            m_btnGroups[8]->addButton(m_radioA);
            m_btnGroups[8]->addButton(m_radioB);
            break;
        }

        if(i < 8) m_btnGroups[i] = new QButtonGroup(this);

        //选择题
        for(int j = 0; j < 4; j++)
        {
            if( i == 8){//多项多选题
                m_checkBtns[j] = new QCheckBox(this);
                m_checkBtns[j]->setText(strList.at(j));
                m_layout->addWidget(m_checkBtns[j],2+j,8);
            }else{//单项选择题
                m_radioBtns[4 * i + j] = new QRadioButton(this);
                m_radioBtns[4 * i + j]->setText(strList.at(j));
                m_layout->addWidget(m_radioBtns[4 * i + j],2+j,i);

                m_btnGroups[i]->addButton(m_radioBtns[4 * i + j]);
            }
        }
    }

    QPushButton *submitBtn = new QPushButton(this);
    submitBtn->setText("提交");
    submitBtn->setFixedSize(100,35);
    connect(submitBtn,SIGNAL(clicked(bool)),this,SLOT(getScore()));
    m_layout->addWidget(submitBtn,6,9);
}

bool ExamDialog::hasNoSelect()
{
    int radioSelects = 0;
    for(int i = 0; i < 8; i++)
    {
        if( m_btnGroups[i]->checkedButton() )
            radioSelects++;
    }

    if(radioSelects != 8)
        return true;

    int checkSelects = 0;
    for(int i = 0; i < 4; i++)
    {
        if(m_checkBtns[i]->isChecked())
            checkSelects++;
    }

    if(checkSelects == 0 || checkSelects == 1)
        return true;

    if(!m_radioA->isChecked() && !m_radioB->isChecked())
        return true;

    return false;
}

void ExamDialog::freshTime()
{
    m_timeGo++;
    QString min = QString::number(m_timeGo / 60);
    QString sec = QString::number(m_timeGo % 60);
    setWindowTitle("考试已用时:" + min + "分" + sec + "秒");
}

void ExamDialog::getScore()
{
    if(hasNoSelect()){
        QMessageBox::information(this,"提示","您有未完成的题目,请完成考试!","是");
        return;
    }

    int scores = 0;
    for(int i = 0; i < 10; i++)
    {
        //单选题计分
        if( i < 8)
            if(m_btnGroups[i]->checkedButton()->text() == m_answerList.at(i))
                scores += 10;

        //多项选择题计分
        if(i == 8){
            QString answer = m_answerList.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;

            bool checkA = m_checkBtns[0]->checkState();
            bool checkB = m_checkBtns[1]->checkState();
            bool checkC = m_checkBtns[2]->checkState();
            bool checkD = m_checkBtns[3]->checkState();

            if( hasA != checkA) continue;
            if( hasB != checkB) continue;
            if( hasC != checkC) continue;
            if( hasD != checkD) continue;

            scores += 10;
        }

        //判断题计分
        if(i == 9){
            if(m_btnGroups[8]->checkedButton()->text() == m_answerList.at(i))
                scores += 10;
        }
    }

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


   

 

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

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

相关文章

清理安卓手机广告

保存脚本另存为 Fuck_AD.sh&#xff0c;在手机执行后体验效果。 echo ""echo " " echo " - 开始执行清理广告库文件" sleep 3files(/data/app/*/*/lib/arm64/libpangleflipped.so/data/app/*/*/lib/arm64/libzeus_direct_dex.so/data/app/*/*/l…

力扣--哈希表13.罗马数字转整数

首先我们可以知道&#xff0c;一个整数&#xff0c;最多由2个罗马数字组成。 思路分析 这个方法能够正确将罗马数字转换为阿拉伯数字的原因在于它遵循了罗马数字的规则&#xff0c;并且对这些规则进行了正确的编码和处理。 罗马数字规则 罗马数字由以下字符组成&#xff1a…

第八届能源、环境与材料科学国际学术会议(EEMS 2024)

文章目录 一、重要信息二、大会简介三、委员会四、征稿主题五、论文出版六、会议议程七、出版信息八、征稿编辑 一、重要信息 会议官网&#xff1a;http://ic-eems.com主办方&#xff1a;常州大学大会时间&#xff1a;2024年06月7-9日大会地点&#xff1a;新加坡 Holiday Inn …

langchian进阶二:LCEL表达式,轻松进行chain的组装

LangChain表达式语言-LCEL&#xff0c;是一种声明式的方式&#xff0c;可以轻松地将链条组合在一起。 你会在这些情况下使用到LCEL表达式: 流式支持 当你用LCEL构建你的链时&#xff0c;你可以得到最佳的首次到令牌的时间(输出的第一块内容出来之前的时间)。对于一些链&#…

C语言.数据结构.顺序表

1.顺序表的概念及结构 1.1线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构&#xff0c;…

创建FreeRTOS工程

创建STM32CubeMX工程 配置时钟 配置FreeRTOS 生成Keil MDK的工程 打开工程 结尾 这就是我们用STM32CubeMX创建的最基本的一个FreeRTOS的工程。可以看到&#xff0c;这个与我们使用stm32开发的裸机程序有相同的地方&#xff0c;也有不同的地方&#xff0c;我们可以发现&am…

Redis 哨兵机制的工作原理——Java全栈知识(22)

Redis 哨兵机制的工作原理 在之前的文章我们讲到了 Redis 的三种集群架构&#xff1a;跳转文章&#xff1a;Redis集群模式 接下来我们详细讲哨兵机制的作用以及实现原理 以下是 Redis 哨兵的结构图 1、Redis 哨兵的作用 哨兵的作用如下&#xff1a; 1、监控&#xff0c;2、…

Mysql基础(七)DQL之select 语句(二)

一 select 语句续 WHERE子句后面跟着的是一个或多个条件,用于指定需要检索的行COUNT(): 多少条数据 where 11 和 count(1) 与 count(*) count(1)、count(*)和count(指定字段)之间的区别 ① order by 排序 mysql 之数据排序扩展 1、使用 order by 语句来实现排序2、排序可…

数据迁移利器登场!Elasticdumpv6.110震撼发布,助你轻松搬迁大数据!

简介 Elasticdump 是一个用于导出和导入 Elasticsearch 数据的工具。它能够从一个 Elasticsearch 集群读取数据并写入到另一个 Elasticsearch 集群、文件系统或其他数据存储&#xff08;例如 S3&#xff09;。这个工具非常有用&#xff0c;特别是在进行数据迁移、备份和恢复操作…

# AI产品经理的自我修养:既懂用户,更懂技术!

今天上班的时候&#xff0c;发现很多AI社群都在讨论一篇播客《一个顶级AI产品经理的自我修养&#xff0c;对谈光年之外产品负责人Hidecloud》&#xff0c;这篇播客的嘉宾是光年之外的产品负责人——Hidecloud&#xff08;张涛&#xff09;&#xff0c;聊了许多关于他在做AI产品…

ubuntu20.04 安装系统后-开机黑屏-nvidia显卡驱动没问题_thinkpad-intel-13700H

文章目录 硬件现象原因&解决 硬件 thinkpad p1 gen6笔记本&#xff0c; intel 13代cpu 13700H,nvidia rtx 2000 Ada laptop gpu 13700H应该是有集显的&#xff0c;但可能没装集显驱动or由于Bios设置的缘故&#xff0c;我的win任务管理器只能看到一个gpu(gpu0)&#xff1…

Spring Boot 01:Spring Boot 项目的两种创建方式

一、前言 记录时间 [2024-05-25] 本文讲述 Spring Boot 项目的两种创建方式&#xff0c;分别是 IDEA 和官网。 由 Spring 官网知&#xff0c;当前 Spring Boot 的最新版本为 3.3.0&#xff0c;需要最低 JDK 版本为 17。 Spring 官网项目创建地址JDK 17 版本下载地址 准备工作…

【Linux网络】端口及UDP协议

文章目录 1.再看四层2.端口号2.1引入linux端口号和进程pid的区别端口号是如何生成的传输层有了pid还设置端口号端口号划分 2.2问题2.3netstat 3.UDP协议3.0每学一个协议 都要讨论一下问题3.1UDP协议3.2谈udp/tcp实际上是在讨论什么&#xff1f; 1.再看四层 2.端口号 端口号(Po…

《计算机网络微课堂》1-6 计算机体系结构

常见的计算机网络体系结构 从本节课开始&#xff0c;我们要用 4 次课的时间来介绍有关计算机网络体系结构的知识&#xff0c;具体包含以下内容&#xff1a; 一&#xff0c;常见的计算机网络体系结构二&#xff0c;计算机网络体系结构分层的必要性三&#xff0c;计算机网络体系…

MPLS LDP原理与配置

1.LDP基本概念 &#xff08;1&#xff09;LDP协议概述 &#xff08;2&#xff09;LDP会话、LDP邻接体、LDP对等体 &#xff08;3&#xff09;LSR ID 与LDP ID &#xff08;4&#xff09;LDP消息 ⦁ 按照消息的功能&#xff0c;LDP消息一共可以分为四大类型&#xff1a;发现…

【UE数字孪生学习笔记】 使用DataSmith对模型快速导入 UE5.3.2使用unreal DataSmith文件

声明&#xff1a;部分内容来自于b站&#xff0c;慕课&#xff0c;公开课等的课件&#xff0c;仅供学习使用。如有问题&#xff0c;请联系删除。 部分内容来自UE官方文档&#xff0c;博客等 UE5.3.2使用 3D Max 导出的unreal DataSmith文件 1. 去UE官网下载DataSmith导出器并导…

QAnything 1.4.1 中的文档解析

2024年初我们开源了QAnything&#xff0c;一个基于检索增强生成式应用&#xff08;RAG&#xff09;的本地知识库问答系统。对于本地知识库&#xff0c;QAnything支持多种格式的文档输入&#xff0c;允许用户上传包括PDF、图片、Word、PowerPoint、Excel、TXT&#xff0c;甚至音…

默认路由实现两个网段互通实验

默认路由实现两个网段互通实验 **默认路由&#xff1a;**是一种特殊的静态路由&#xff0c;当路由表中与数据包目的地址没有匹配的表项时&#xff0c;数据包将根据默认路由条目进行转发。默认路由在某些时候是非常有效的&#xff0c;例如在末梢网络中&#xff0c;默认路由可以…

牛客NC334 字典序第K小【困难 10叉树 Java/Go/PHP/C++】,力扣 440. 字典序的第K小数字

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/670c2bda374241d7ae06ade60de33e8b https://leetcode.cn/problems/k-th-smallest-in-lexicographical-order/description/ 本答案核心 10叉树, 数学规律Java代码 import java.util.*;public class Solution {…

【Android开发】Android请求出现网络请求失败,HTTP请求,安全网络通信与权限管理

额外权限 要有这个权限&#xff1a; <uses-permission android:name"android.permission.INTERNET" />HTTP安全考虑 从 Android 9&#xff08;API 级别 28&#xff09;开始&#xff0c;默认情况下不支持通过 HTTP 访问网络&#xff0c;而要求使用 HTTPS。这…