基于Qt实现驾校科目考试系统的示例代码

目录
  • 1.设置登录界面
  • 2.登录功能实现
    • 2.1验证邮箱地址
    • 2.2账号密码登录
    • 2.3密码隐藏
  • 3.考试界面开发
    • 3.1考试用时
    • 3.2题目布局
    • 3.3按钮布局
    • 3.4提交分数
    • 3.5窗口交互
  • 4.发布项目
    • 4.1更改编译路径
    • 4.2设置图标
    • 4.3通过dos进行项目打包

1.设置登录界面

LoginDialog::LoginDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::LoginDialog)
{
    ui->setupUi(this);
    ui->imgLabel->setScaledContents(true);//设置填充
    this->resize(ui->imgLabel->width(),ui->imgLabel->height());//设置窗口大小

    //设置窗口标题
    this->setWindowTitle(("驾校科目一考试登录"));
    //设置窗口风格
    this->setWindowFlags(Qt::Dialog |Qt::WindowCloseButtonHint);
}

2.登录功能实现

2.1验证邮箱地址

首先判断输入的账号是否符合邮箱格式 ,如果符合则进行登录验证,否则提示格式错误

void LoginDialog::on_loginButton_clicked()
{
    //首先通过正则表达式判断账号是否是一个合法的邮箱格式
    //^:表示规则字符串开始、$:表示规则字符串的结束
    //+:表示匹配次数≥1次、*:表示匹配任意次数(可为0次) {n,m}表示匹配次数最少n次 最多m次
    QRegExp rx("^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$");//初始化时指定规则字符串
    bool res = rx.exactMatch(ui->accountEdit->text());//对用户输入的账号进行匹配
    if(res){//匹配成功
        QMessageBox::information(this,"提示","欢迎登录科目一考试科目系统");
    }else{//匹配不成功
        QMessageBox::information(this,"提示","非法邮箱地址!请您重新输入");
        ui->accountEdit->clear();//清空账号输入框
        ui->codeEdit->clear();//清空密码输入框
        ui->accountEdit->setFocus();//账号输入框聚焦
        return ;
    }

}

2.2账号密码登录

当账号格式合法后,读取保存账号和密码的文档进行匹配

if(res){//匹配成功
//QMessageBox::information(this,"提示","欢迎登录科目一考试科目系统");
QString filename;//文件路径
QString AccInput;//用户输入账号
QString strCode;//用户输入密码
QString strLine;//每次读取一行数据
QStringList strList;//分割读取一行数据

filename="../account.txt";//设置文件路径
AccInput=ui->accountEdit->text();//获取账号
strCode=ui->codeEdit->text();//获取密码

QFile file(filename);//初始化
QTextStream stream(&file);//文本类型文件流
//指定只读方式打开,指定文件类型式文本类型
if(file.open(QIODevice::ReadOnly|QIODevice::Text)){
    //打开成功
    while(!stream.atEnd()){
        strLine=stream.readLine();//每次读取一行
        strList = strLine.split(",");//将读取到的行按","分割
        if(AccInput==strList.at(0)){
            if(strCode==strList.at(1)){
                //账号和密码匹配成功
                QMessageBox::information(this,"提示","欢迎进入科目一考试系统");
                file.close();
                return ;
            }else{
                //账号匹配成功&密码不成功
                QMessageBox::information(this,"提示","密码错误!请重新输入!");
                ui->codeEdit->clear();
                ui->codeEdit->setFocus();
                file.close();
                return ;
            }
        }
    }
    QMessageBox::information(this,"提示","输入账号有误!请重新输入!");
    ui->accountEdit->clear();//清空账号输入框
    ui->codeEdit->clear();//清空密码输入框
    ui->accountEdit->setFocus();//账号输入框聚焦
    file.close();
    return;
}

2.3密码隐藏

将密码控件的echoMode属性值改为Password即可

3.考试界面开发

3.1考试用时

首先添加一个考试对话框类;在考试对话框类中添加QTimer和int属性用于表示计时器和已用时;设定计时器的时间间隔为1s,通过connect函数将计时器与已用时显示信号槽连接起来

examDialog.h

#ifndef EXAMDIALOG_H
#define EXAMDIALOG_H
#include<QDialog>
#include<QTimer>
class ExamDialog : public QDialog
{
    Q_OBJECT//使用信号槽
public:
    ExamDialog(QWidget* parent=0);
    void initTimer();
private:
    QTimer*m_timer;//计时器
    int m_timeGo;//考试已用时
private slots:  //私有槽方法
    void freshTime();
};

#endif // EXAMDIALOG_H

examDialog.cpp

#include "examdialog.h"

ExamDialog::ExamDialog(QWidget* parent):QDialog(parent)
{
    setWindowTitle("考试已用时:0分0秒");
    initTimer();
}

void ExamDialog::initTimer()
{
    m_timeGo=0;
    m_timer=new QTimer(this);
    m_timer->setInterval(1000);//设置计时器时间间隔1s
    m_timer->start();//启动计时器
    //通过connect方法,连接信号槽。m_timer每发送timeout()信号时,由this执行槽方法freshTime()
    connect(m_timer,SIGNAL(timeout()),this,SLOT(freshTime()));

}

void ExamDialog::freshTime()
{
    //刷新考试用时
    m_timeGo++;
    QString min=QString::number(m_timeGo/60);//计算分钟,将整数转QString
    QString sec=QString::number(m_timeGo%60);
    setWindowTitle("考试已用时:"+min+"分"+sec+"秒");
}

3.2题目布局

添加属性以及初始化方法

public:
    void initLayout();  //初始化布局管理器
    bool initTextEdit();//初始化文本编辑器
    void initButton();  //初始化按钮及标签
private:

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

在initLayout函数中,设置当前窗口为为管理器父窗口,规定控件间的距离以及控件和窗体间的距离

void ExamDialog::initLayout()
{
    //以当前窗口作为父窗口
    m_layout=new QGridLayout(this);
    m_layout->setSpacing(10);//设置控件之间的间距
    m_layout->setMargin(10);//设置窗体与控件键的边距

}

在initTextEdit函数中,读取文本中的题目信息并将答案行单独存储,将读取到的题目信息显示在控件中,并将控件交给布局管理器在窗体上布局。

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;
            }else if((nLines%6==0&&nLines>=6&&nLines<=6*9)||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;
    }
}

在初始化函数中对窗体背景和字体进行一些设置

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()){

    }else{
        //读取失败
        QMessageBox::information(this,"提示","初始化题库数据文件失败!");
        //当前应用程序立刻响应槽方法quit
        QTimer::singleShot(0,qApp,SLOT(quit()));
    }
}

3.3按钮布局

布局方法就是先将控件初始化,然后交给布局管理器进行布局。但要注意的是单选按钮的分组:每个单选题的四个按钮为一组,判断题的两个按钮为一组

新添加QbuttonGroup属性

private:
    QButtonGroup* m_btnGroups[9];//单选按钮分组

在初始换按钮函数中

void ExamDialog::initButton()
{
    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);
        }
        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 if(i<8){
                //单选题
                m_radioBtns[i*4+j]=new QRadioButton(this);
                m_radioBtns[i*4+j]->setText(strList.at(j));
                m_layout->addWidget(m_radioBtns[i*4+j],2+j,i);

                m_btnGroups[i]->addButton(m_radioBtns[i*4+j]);
            }
        }
        //提交按钮
        QPushButton*submitBtn=new QPushButton(this);
        submitBtn->setText("提交");
        submitBtn->setFixedSize(100,35);
        m_layout->addWidget(submitBtn,6,9);
    }
}

3.4提交分数

首先将提交按钮与信号槽连接

connect(submitBtn,SIGNAL(clicked(bool)),this,SLOT(getScore()));

在计算分数前先判断题目是否全部完成,然后根据读取的答案计算分数

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 checkSelect=0;
    for(int i=0;i<4;++i){
        if(m_checkBtns[i]->isChecked()){
            checkSelect++;
        }
    }
    //多选题未选或只选了一个也算未完成
    if(checkSelect==0||checkSelect==1){
        return true;
    }
    //判断题
    if(!m_radioA->isChecked()&&!m_radioB->isChecked()){
        return true;
    }
    return false;
}

void ExamDialog::getScore()
{
    if(hasNoSelect()){
        //有未完成的题目
        QMessageBox::information(this,"提示","您有未完成的题目!请完成考试","是");
        return ;
    }else{
        //开始统分
        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;
                hasA=answer.contains("A");
                hasB=answer.contains("B");
                hasC=answer.contains("C");
                hasD=answer.contains("D");

                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||hasB!=checkB||hasC!=checkC||hasD!=checkD){
                    //答案有不一致的
                    continue;
                }else{
                    scores+=10;
                }
            }
            //判断题统分
            if(i==9){
                if(m_btnGroups[8]->checkedButton()->text()==m_answerList.at(i)){
                    scores+=10;
                }
            }
        }
        int res = QMessageBox::information(this,"提示","您所得分数为:"+QString::number(scores)+"分。是否重新考试?",QMessageBox::Yes|QMessageBox::No);
        if(res==QMessageBox::Yes){
            //重新考试
            return;
        }else{
            //不想重新考试
            close();
        }
    }
}

3.5窗口交互

实现登录窗口与考试窗口的连接

当用户登录成功后通过done函数发送一个Accepted,当用户点击取消时发送一个Rejected,然后在主函数中进行判断

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    LoginDialog loginDialog;
    int res = loginDialog.exec();   //以模态方式运行
    if(res==QDialog::Accepted){
        ExamDialog examDialog;
        return a.exec();
    }else{
        return 0;
    }
    return a.exec();
}

4.发布项目

4.1更改编译路径

将当前编译路径由debug转为当前文件所在路径

4.2设置图标

在项目文件中通过 RC_ICONS加载图标

RC_ICONS += examsys.ico

图标已经更改过来了

4.3通过dos进行项目打包

将项目由DeBug模式改为Release模式,并编译

建立一个文件夹作为发布文件,将Release下生成的.exe文件和需要的文档拷贝进来

进入要发布文件夹路径,然后输入windeployqt 文件名.exe,点击回车

打包完成

如果提示 windeployqt不是命令的话需要将安装的qt的bin路径添加到环境变量中

到此这篇关于基于Qt实现驾校科目考试系统的示例代码的文章就介绍到这了,更多相关Qt驾校科目考试系统内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 基于Qt OpenCV实现图像数据采集软件

    效果图 示例代码 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<QTimer> #include<QDebug> #include<QDateTime> #include<opencv2/opencv.hpp> using namespace cv; using namespace std; QT_BEGIN_NAMESPACE namespace Ui { class

  • Python+PyQt5+MySQL实现天气管理系统

    在本篇博客中,我利用Python语言其编写界面库PyQt5,然后通过连接MySQL数据库,实现了一个简单的天气管理小系统,该系统包含简单的增删查改四个主要功能.本文旨在解析实现的程序,能够让读者快速了解PyQt5图形界面库,然后可以初步实现这样一个小的系统程序. PyQt5简介 PyQt5本身来自C++的界面库Qt,经过一系列的封装移植到Python里面,作为Python的一个图像界面库,它继承了Python语言简单易实现的特点,可以实现基本的界面效果.里面有许多类实现了我们想要的窗体.表格.文

  • Qt实现一个简单的word文档编辑器

    目录 1.先看效果图 2.需要用到的类 2.1字体选择下拉框:QFontComboBox. 2.2颜色对话框:QColorDialog 2.3QTextCharFormat 3.源码 1.先看效果图 可以设置文字的属性.文字颜色.字体类型.以下示例仅供参考,有的地方还是不完善. 2.需要用到的类 2.1字体选择下拉框:QFontComboBox. QFontComboBox是一个让用户选择字体的组合框.组合框中填充了按字母顺序排列的字体族名称列表. 常用方法: 获取当前的字体 QFont cur

  • Qt实现简易QQ聊天界面

    本文实例为大家分享了Qt实现简易QQ聊天界面的具体代码,供大家参考,具体内容如下 代码 myDialog.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QWidget> #include <QToolButton> #include <QVBoxLayout> #include <QHBoxLayout> #include <QList> class MyDialog : public

  • 基于PyQT5制作一个课堂点名系统

    刷抖音的时候发现一个老师在用的课堂点名系统.用PyQt5实现了一下同款,导入学生姓名,测试了一下完美运行. 操作效果展示: 完整源代码块还是放在了文章的最后面 使用的时候准备好学生姓名的文件,使用导入数据的按钮直接导入就可以开始点名了.新建一个文本文档,将姓名设置设置好,姓名文件示例如下. 使用系统库或者第三方库都比较常规,这里就不一一介绍了. from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore im

  • python+PyQT实现系统桌面时钟

    用Python + PyQT写的一个系统桌面时钟,刚学习Python,写的比较简陋,但是基本的功能还可以. 功能: ①窗体在应用程序最上层,不用但是打开其他应用后看不到时间 ②左键双击全屏,可以做小屏保使用,再次双击退出全屏. ③系统托盘图标,主要参考PyQt4源码目录中的PyQt4\examples\desktop\systray下的程序 ④鼠标右键,将程序最小化 使用时需要heart.svg放在源代码同级目录下,[文件可在PyQt4示例代码目录下PyQt4\examples\desktop\

  • 基于Qt实现驾校科目考试系统的示例代码

    目录 1.设置登录界面 2.登录功能实现 2.1验证邮箱地址 2.2账号密码登录 2.3密码隐藏 3.考试界面开发 3.1考试用时 3.2题目布局 3.3按钮布局 3.4提交分数 3.5窗口交互 4.发布项目 4.1更改编译路径 4.2设置图标 4.3通过dos进行项目打包 1.设置登录界面 LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::LoginDialog) { ui->setupUi(this

  • Django框架实现在线考试系统的示例代码

    1.Django的简介 Django是一个基于MVC构造的框架.但是在Django中,控制器接受用户输入的部分由框架自行处理,所以 Django 里更关注的是模型(Model).模板(Template)和视图(Views),称为 MTV模式.它们各自的职责如下: 层次 职责 模型(Model),即数据存取层 模型(Model),即数据存取层 模板(Template),即表现层 处理与表现相关的决定: 如何在页面或其他类型文档中进行显示. 视图(View),即业务逻辑层 存取模型及调取恰当模板的相

  • 基于Qt实现简易GIF播放器的示例代码

    目录 一.项目介绍 二.项目基本配置 三.UI界面设计 四.主程序实现 4.1 mainwindow.h头文件 4.2 mainwindow.cpp源文件 五.效果演示 一.项目介绍 利用Qt设计一个简易GIF播放器,可以播放GIF动画.其基本功能有载入文件.播放.暂停.停止.快进和快退. 二.项目基本配置 新建一个Qt案例,项目名称为“GIFTest”,基类选择“QMainWindow”,创建UI界面复选框的选中状态,完成项目创建. 三.UI界面设计 UI界面如下: 界面中创建了8个控件,其名

  • 基于Python实现随机点名系统的示例代码

    目录 效果展示 代码展示 导入模块 子线程调用 应用初始化信息 姓名信息布局 开始信息布局 数据信息布局 整体布局 运行 大家好,我是了不起! 在某些难以抉择得时候,我们经常要用外力来帮助我们做出选择 比如,梁山出征方腊前沙场点兵,挑选先锋的场景 这个时候,有一个随机点名系统就非常好啦,毕竟我水泊梁山的名号~ 效果展示 创建一个这样的文件夹,然后把要随机点名的名字写在里面 导入后,这里就显示你导入了多少人员信息 点击开始点名后,会随机从导入名字里挑选一位幸运儿~ 效果大概就是这样,下面我们来看看

  • 基于Java实现中文分词系统的示例代码

    目录 1.问题描述 2.相关工作 3.系统框架和算法设计 3.1系统整体框架 1.问题描述 中文分词 (Chinese Word Segmentation) 指的是将一个汉字序列切分成一个一个单独的词.分词就是将连续的字序列按照一定的规范重新组合成词序列的过程.我们知道,在英文的行文中,单词之间是以空格作为自然分界符的,而中文只是字.句和段能通过明显的分界符来简单划界,唯独词没有一个形式上的分界符,虽然英文也同样存在短语的划分问题,不过在词这一层上,中文比之英文要复杂的多.困难的多. 而对于中文

  • C/C++实现个人收支系统的示例代码

    昨天朋友委托我做一个基于C++的课程小设计,题目如下: 设计一个简单的个人收支管理系统,至少包括如下功能: 1.逐笔输入个人收入或支出的明细,写入到文件保存,可不断进行输入和追加. 输入的明细数据包括:收支明细类别编码.发生日期.金额.备注. 1)为了简化用户的输入,类别编码由字母和数字构成:"a"表示收入."b"表示支 出,数字是大类下的编号.类别编码及类别名称的对应由自己定义.组织在程序中 并输出展示.比如 a1 表示收入类的生活费,b1 表示支出类的学习,编号

  • 基于Docker+Selenium Grid的测试技术应用示例代码

    Selenium Grid介绍 尽管在未来将会推出的Selenium 4.0版本中对Selenium Grid的一些新特性进行了说明,但是目前来看官方并没有太多详细文档供大家参考,所以本书中仍结合目前被广泛使用的Selenium Grid 版本进行讲解. 正如其官网对Selenium Grid的描述,它是一个智能代理服务器,允许Selenium测试将命令路由到远程Web浏览器实例.其目的是提供一种在多台计算机上并行运行测试的简便方法.使用Selenium Grid,一台服务器充当将JSON格式的

  • Qt编写地图实现闪烁点图的示例代码

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 Qt作为一个超大型的一站式GUI超市开发集成环境,不仅集成了大量的可视化UI组件,还提供了网络库.数据库操作.文件操作等类库,封装的还是相当精彩一步到位,根据个人身边的一些程序员朋友了解,自从用了Qt以来发现越来越喜欢用Qt本身的类来处理,除非一些要求很高的应用场景比如并发网络才需要去使用第三方库,不然就是直接使用Qt封装好的类,用起来非常爽,尤其是类的名称和方法的名称,几乎很自然的就能打出来. Qt除了内置了各种U

  • QT编写地图实现设备点位的示例代码

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 在学习JS语法的时候发现其实程序都大同小异,正所谓一通百通,熟悉各大概的语法以后基本都可以上手,和C++最大的不同就是他没有数据类型的概念,作为解释性的语言,是在执行的时候自动去转换数据类型,工作都交给解释器做掉了,这样就大大方便了程序员,到处var即可,哪怕是数组啊对象啊,万物皆var,只有当真正赋值的时候,才知道具体的数据类型. 在地图应用的相关项目中,在地图上标识一些设备点,并对点进行交互这个功能用的最多的,于

  • Qt实现数据导出到xls的示例代码

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 导入导出数据到csv由于语法简单,适用场景有限,于是乎还是必须再造一个轮子导出数据到xls,在经历过数十年的项目实战经验中不断调整和优化.尤其记得当初第一个版本v0.01大概在2011年左右完成的,当时是公司项目运行在嵌入式板子上,需要导出警情记录,拷贝到电脑上打印,由于嵌入式根本没有也不可能去安装excel等软件,硬着头皮去研究了xml格式的xls文件,按照那个规则组合成简单的导出数据,这个思路想法理论上比QtXl

随机推荐