一、简介
二、UI界面设计、读txt文件
三、QTimer定时器、随机数
四、不重复点名
五、源代码
一、简介
上学时某老师用点名器随机点名,现在就来制作一个点名器。编写随机点名器,主要有以下几个步骤:
ui界面设计 --》 读取data.txt文件中的姓名信息 --》 QTimer定时器定时触发生成随机数的函数 --》 设置点名策略为不重复点名。
在源文件目录下添加 data1.txt 记录所有同学的姓名;
内容如下(本例中有40个名字):
最终结果如下:
二、UI界面设计、读txt文件
1. 新建mainWindow项目,项目名为“Rand_select”。双击.ui文件,在ui界面下设计主窗口为如下形式:1
拖入一个TextEdit(用于显示文本信息)、两个PushButton空间(用于触发和暂停QTimer定时器)。“开始”按钮对象名设置为start_Btn,暂停按钮对象名设置为stop_Btn。
2.读取data.txt 文件
在mainwindow.h文件下MainWindow类下添加成员函数:void readFile()用于读取 .txt文件。
读取文件的方法为:使用QTextStream,readAll()将文件内容全部读取至QString对象中,最后用空格分割符号将所有名字放到QString数组中。
void readFile()代码如下:
void MainWindow::readFile()
{
//构造一个以data1.txt为文件名的QFile对象
QFile file("../Rand_select/data1.txt");
//文件以只读方式打开 || 在读取时,将行结束符转换成 \n
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug()<< "open file failure";
return;
}
else
{
QString array;
//创建QTextStream流操作对象,与QFile对象file连接
QTextStream in(&file);
//读取所有文本
array = in.readAll();
//trimmed():移除字符串两端空白符,simplified():移除字符串两端的空白字符,
//使用单个空格字符“ ”代替字符串中出现的空白字符。
array = array.trimmed();
array = array.simplified();
int i=0,k=0;
while(i<array.size())
{
//.at(int position):返回当前字符的位置index
name_data[k] += array.at(i);
name_data[k]=name_data[k].trimmed();
if(array.at(i) == " ")
{
k++;
}
i++;
}
}
file.close();
}
三、QTimer定时器、随机数
QTimer类为我们提供了一个即可重复触发又可单次触发的定时器;
重复触发,即每隔一段时间(单位是毫秒)就会发射信号。典型的用法如下:
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(***)); // ***即响应函数
timer->start(1000); // 每隔1000ms
现在在MainWindow类下添加QTimer成员:QTimer *timer = new QTimer;然后在构造函数中添加如下代码:
readFile();
connect(timer,SIGNAL(timeout()),this,SLOT(srand()));
响应函数srand()代码如下:
void MainWindow::srand()
{
//QTime(int h,int m, int s, int ms):构造一个具有初始时间的QTime对象
//.msecsTo(QTime::curentTime()):计算距离当前时间的毫秒数
//qsrand()使用非固定值来作为种子,希望函数在每次调用(间隔大于1ms)时生成的随机数不一样。
qsrand(QTime(0,0,0,0).msecsTo((QTime::currentTime())));
ui->textEdit->clear();
int num = qrand()%total;
ui->textEdit->setText(name_data[num]);
}
四、不重复点名
不重复点名策略为:每当界面暂停按钮点了一次(即点了一次名),记录该名字,然后将改名字在QString array中除去,那么array元素就减少一个。
打开ui界面,右键“暂停”按钮,转到槽,选择clicked(),槽函数内容如下:
void MainWindow::on_stop_Btn_clicked()
{
timer->stop();
//num标记上次点名点点到的名字,在QString中的位置
int num=0;
QString str = ui->textEdit->toPlainText();
//total为数组元素个数,是static全局变量
for(int i=0;i<total;i++)
{
if(str == name_data[i])
{
num = i;
break;
}
}
for(int i=0;i<total-1;i++)
{
if(i>=num)
{
name_data[i]=name_data[i+1];
}
}
total--;
}
五、源代码
//*******************mainwindow.h*******************************
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void readFile();
private slots:
void on_start_Btn_clicked();
void srand();
void on_stop_Btn_clicked();
private:
Ui::MainWindow *ui;
QString name_data[41];
QTimer *timer = new QTimer;
};
#endif // MAINWINDOW_H
//**************************mainwindow.cpp*******************************
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QDebug>
#include <QIODevice>
#include <QTextStream>
#include <QtGlobal>
#include <QTime>
static int total = 41;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
readFile();
ui->textEdit->setText("点名");
ui->textEdit->setReadOnly(true);
connect(timer,SIGNAL(timeout()),this,SLOT(srand()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::readFile()
{
//构造一个以data1.txt为文件名的QFile对象
QFile file("../Rand_select/data1.txt");
//文件以只读方式打开 || 在读取时,将行结束符转换成 \n
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug()<< "open file failure";
return;
}
else
{
QString array;
//创建QTextStream流操作对象,与QFile对象file连接
QTextStream in(&file);
//读取所有文本
array = in.readAll();
//trimmed():移除字符串两端空白符,simplified():移除字符串两端的空白字符,
//使用单个空格字符“ ”代替字符串中出现的空白字符。
array = array.trimmed();
//qDebug()<<array;
array = array.simplified();
//qDebug()<<array;
int i=0,k=0;
while(i<array.size())
{
//.at(int position):返回当前字符的位置index
name_data[k] += array.at(i);
name_data[k]=name_data[k].trimmed();
if(array.at(i) == " ")
{
k++;
}
i++;
}
}
file.close();
}
void MainWindow::on_start_Btn_clicked()
{
timer->start(100);
}
void MainWindow::on_stop_Btn_clicked()
{
timer->stop();
int num=0;
QString str = ui->textEdit->toPlainText();
for(int i=0;i<total;i++)
{
if(str == name_data[i])
{
num = i;
break;
}
}
for(int i=0;i<total-1;i++)
{
if(i>=num)
{
name_data[i]=name_data[i+1];
}
}
total--;
}
void MainWindow::srand()
{
//QTime(int h,int m, int s, int ms):构造一个具有初始时间的QTime对象
//.msecsTo(QTime::curentTime()):计算距离当前时间的毫秒数
//qsrand()使用非固定值来作为种子,希望函数在每次调用(间隔大于1ms)时生成的随机数不一样。
qsrand(QTime(0,0,0,0).msecsTo((QTime::currentTime())));
ui->textEdit->clear();
int num = qrand()%total;
ui->textEdit->setText(name_data[num]);
}
//**************************main.cpp*******************************
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setWindowTitle("点名!");
w.show();
return a.exec();
}