QT 製作隨機點名器
一、簡介
二、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();
}