从QThread继承方式
1. qdicethread.h
#ifndef QDICETHREAD_H
#define QDICETHREAD_H
#include <QObject>
#include <QThread>
class QDiceThread : public QThread
{
Q_OBJECT
public:
explicit QDiceThread(QThread *parent = nullptr);
void diceBegin();
void dicePause();
void stopThread();
private:
int m_seq = 0;
int m_diceValue;
bool m_Paused = true;
bool m_stop = false;
// QThread interface
protected:
virtual void run() override;
signals:
void newValue(int seq, int diceValue);
};
#endif // QDICETHREAD_H
2. qdicethread.cpp
#include "qdicethread.h"
#include <QTime>
QDiceThread::QDiceThread(QThread *parent)
: QThread{parent}
{
}
void QDiceThread::diceBegin()
{
//开始掷骰子
m_Paused = false;
}
void QDiceThread::dicePause()
{
//暂停掷骰子
m_Paused = true;
}
void QDiceThread::stopThread()
{
//停止线程
m_stop = true;
}
void QDiceThread::run()
{
//线程任务
m_stop = false;
m_seq = 0;
//随机数初始化,qsrand是线程安全的
qsrand(QTime::currentTime().msec());
//循环主体
while(!m_stop)
{
if(!m_Paused)
{
m_diceValue = qrand();
m_diceValue = (m_diceValue % 6) + 1;
m_seq++;
//发送信号
emit newValue(m_seq, m_diceValue);
}
//现场休眠500ms
msleep(500);
}
//相当与exit(0), 退出线程的事件循环
quit();
}
3. dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QWidget>
#include <QDialog>
#include "qdicethread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
private:
Ui::Dialog *ui;
private:
QDiceThread threadA;
protected:
virtual void closeEvent(QCloseEvent *event) override;
private slots:
void onThreadA_started();
void onThreadA_finished();
void onThreadA_newValue(int seq, int diceValue);
void on_pushButton_startThread_clicked();
void on_pushButton_stopThread_clicked();
void on_pushButton_start_clicked();
void on_pushButton_pause_clicked();
void on_pushButton_clear_clicked();
};
#endif // DIALOG_H
4. dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QCloseEvent>
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
//信号连接
connect(&threadA, SIGNAL(started()), this, SLOT(onThreadA_started()));
connect(&threadA, SIGNAL(finished()), this, SLOT(onThreadA_finished()));
connect(&threadA, SIGNAL(newValue(int, int)), this, SLOT(onThreadA_newValue(int, int)));
}
Dialog::~Dialog()
{
}
void Dialog::closeEvent(QCloseEvent *event)
{
//窗口关闭事件,必须结束线程
if(threadA.isRunning())
{
threadA.stopThread();
threadA.wait();
}
event->accept();
}
void Dialog::onThreadA_started()
{
//状态
ui->label_status->setText("Thread状态: thread started");
}
void Dialog::onThreadA_finished()
{
//状态
ui->label_status->setText("Thread状态: thread finished");
}
void Dialog::onThreadA_newValue(int seq, int diceValue)
{
QString str = QString::asprintf("第 %d 次掷骰子,点数为: %d\r\n", seq, diceValue);
ui->textEdit->append(str);
ui->label_num->setText(QString("%1").arg(diceValue));
}
void Dialog::on_pushButton_startThread_clicked()
{
//启动线程
threadA.start();
ui->pushButton_start->setEnabled(false);
ui->pushButton_stopThread->setEnabled(true);
ui->pushButton_start->setEnabled(true);
ui->pushButton_pause->setEnabled(false);
}
void Dialog::on_pushButton_stopThread_clicked()
{
//结束线程
threadA.stopThread();
threadA.wait();
ui->pushButton_start->setEnabled(true);
ui->pushButton_stopThread->setEnabled(false);
ui->pushButton_start->setEnabled(false);
ui->pushButton_pause->setEnabled(false);
}
void Dialog::on_pushButton_start_clicked()
{
//开始掷骰子
threadA.diceBegin();
ui->pushButton_start->setEnabled(false);
ui->pushButton_pause->setEnabled(true);
}
void Dialog::on_pushButton_pause_clicked()
{
//暂停掷骰子
threadA.dicePause();
ui->pushButton_start->setEnabled(true);
ui->pushButton_pause->setEnabled(false);
}
void Dialog::on_pushButton_clear_clicked()
{
ui->textEdit->clear();
}