【qt】考试系统项目

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

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

目录

  • 一.登录窗口
    • 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_NAMESPACEclass loginDialog : public QDialog
{Q_OBJECTpublic: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.mzph.cn/bicheng/46382.shtml

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

相关文章

从信息化、数字化、智能化到企业大模型应用

新时代背景下&#xff0c;数字经济发展速度之快、辐射范围之广、影响程度之深前所未有&#xff0c;5G、大数据、云计算、人工智能、区块链等技术加速创新&#xff0c;全域融入经济社会、民生服务全过程&#xff0c;成为资源要素重组、经济结构重塑、竞争格局重构的关键力量。千…

Visual Studio 安装程序无法执行修复或更新

一.问题场景 出现问题的场景&#xff1a;当你的VS已经安装但是无法在工具中下载新组件或者卸载了当时一直无法安装。 二.问题原因 如果计算机上的 Visual Studio 实例已损坏&#xff0c;则可能会出现此问题。 三.解决方法 如果之前尝试修复或更新 Visual Studio 失败&…

浅谈RLHF---人类反馈强化学习

浅谈RLHF&#xff08;人类反馈强化学习&#xff09; RLHF&#xff08;Reinforcement Learning fromHuman Feedback&#xff09;人类反馈强化学习 RLHF是[Reinforcement Learning from Human Feedback的缩写&#xff0c;即从人类反馈中进行强化学习。这是一种结合了机器学习中…

51单片机6(P0P1P2P3结构框架图)

一、GPIO结构框架图与工作原理 1、接下来我们介绍一下这个GPIO结构框图和工作原理&#xff0c;我们使用51单片机的GPIO分为了P0&#xff0c;P1&#xff0c;P2&#xff0c;P3这四组端口&#xff0c;下面我们就分别来介绍这四组端口它的一个内部结构&#xff0c;只有了解了内部的…

[PM]原型与交互设计

原型分类 1.草图原型 手绘图稿, 规划的早期,整理思路会使用 2.低保真原型 简单交互, 无需配色, 黑白灰为主, 产品规划和评审阶段使用 标准化的低保真原型是高保真原型的基础 3.高保真原型 复杂交互, 一般用于公开演示, 产品先产出低保真原型, 设计师根据原型产出设计稿 低保…

Vue3学习体验(一)

搭建工程 使用vue-cli脚手架创建vue3工程 vue create vue3-app-vue-cliVue-cli官网&#xff1a;https://cli.vuejs.org/zh/guide/installation.html 使用vite搭建vue3工程 npm init表示临时的下载vite应用来创建vue3工程&#xff0c;工程名称为vue3-app-vite npm init vit…

mount挂载

1&#xff09;Vmvare挂载光驱设备 安装光驱设备后&#xff0c;可以看到设备文件。 ls /dev/sr0 ll /dev/cdrom虽然设备是以文件的形式出现的&#xff0c;但和一般的文件不一样。 2&#xff09;mount挂载 目录是目录&#xff0c;设备是设备&#xff0c;mount挂载可以让目录成…

数据结构——查找(线性表的查找与树表的查找)

目录 1.查找 1.查找的基本概念 1.在哪里找&#xff1f; 2.什么查找&#xff1f; 3.查找成功与否&#xff1f; 4.查找的目的是什么&#xff1f; 5.查找表怎么分类&#xff1f; 6.如何评价查找算法&#xff1f; 7.查找的过程中我们要研究什么&#xff1f; 2.线性表…

Spring webflux基础核心技术

一、 用操作符转换响应式流 1 、 映射响应式流元素 转换序列的最自然方式是将每个元素映射到一个新值。 Flux 和 Mono 给出了 map 操作符&#xff0c;具有 map(Function<T&#xff0c;R>) 签名的方法可用于逐个处理元素。 当操作符将元素的类型从 T 转变为 R 时&#xf…

基于conda包的环境创建、激活、管理与删除

Anaconda是一个免费、易于安装的包管理器、环境管理器和 Python 发行版&#xff0c;支持平台包括Windows、macOS 和 Linux。下载安装地址&#xff1a;Download Anaconda Distribution | Anaconda 很多不同的项目可能需要使用不同的环境。例如某个项目需要使用pytorch1.6&#x…

SAP 消息输出 - Adobe Form

目录 1 安装链接 2 前台配置 - Fiori app 2.1 维护表单模板 (maintain form templates) 2.2 管理微标 (manage logos) 2.3 管理文本 (manage texts) 3 后台配置 3.1 定义表单输出规则 3.2 分配表单模板 SAP 消息输出&#xff0c;不仅是企业内部用来记录关键业务操作也是…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(一)-3GPP TR 22.829 V17.1.0技术报告

本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。 下载…

算法导论 总结索引 | 第五部分 第十八章:B树

1、B 树是 为磁盘或其他直接存取的辅助存储设备 而设计的一种平衡搜索树。B 树类似于红黑树&#xff0c;在降低磁盘 I/O 操作次数方面要更好一些。许多数据库系统 使用 B 树 或者 B 树 的变种来存储信息 2、B 树与红黑树的不同之处 在于 B 树的结点 可以有很多孩子&#xff0c…

STM32-寄存器点灯案例详解

本文以PA1引脚点亮LED灯为案例&#xff0c;解析了STM32寄存器操作的配置过程&#xff0c;以及从手册查询方法和寄存器配置步骤。 一、概念 1.十六进制和二进制之间相互转换关系 首先&#xff0c;需要了解十六进制和二进制之间的基本转换方法。十六进制是一种基数为16的数制&…

制作显卡版docker并配置TensorTR环境

感谢阅读 相关概念docker准备下载一个自己电脑cuda匹配的docker镜像拉取以及启动镜像安装cudaTensorRT部署教程 相关概念 TensorRT是可以在NVIDIA各种GPU硬件平台下运行的一个模型推理框架&#xff0c;支持C和Python推理。即我们利用Pytorch&#xff0c;Tensorflow或者其它框架…

frameworks 之FallbackHome

frameworks 之FallbackHome FallbackHome 启动启动 Activity 流程创建进程ActivityThrad 与 AMS启动真正的 Launcher mActivityManagerService 创建后会启动 FallbackHome 再启动桌面程序。因为此时还没解锁&#xff0c;桌面又涉及很多其他应用程序相关&#xff0c;所以要等待用…

【Python】数据处理(mongodb、布隆过滤器、索引)

数据 数据预处理 df pd.read_csv(file_path, encodingANSI) csv的编码方式一定要用 ANSI。要不然会出现各种报错 import pandas as pd from datetime import datetime# 读取CSV文件 file_path book_douban.csv df pd.read_csv(file_path, encodingANSI)# 定义一个函数来…

基于SpringBoot协同过滤算法商品推荐系统(源码+lw+部署文档+讲解等)

前言&#xff1a; 博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBo…

【C++】入门基础(引用、inline、nullptr)

目录 一.引用 1.引用的定义 2.引用的特性 3.引用的使用场景 4.const引用 5.引用和指针的区别 二.inline 三.nullptr 一.引用 1.引用的定义 引用不是新定义一个变量&#xff0c;而是给已经存在的变量取一个别名&#xff0c;编译器不会给引用变量开辟内存空间&#xff0c…

SpringSecurity6 | 获取登录用户的认证信息

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringSecurity6 ✨特色专栏: MySQL学习 🥭本文内容: SpringSecurity6 | 获取登录用户的认证信息 📚个人知识库: Leo知识库…