先看一下QThread 类功能简单介绍
将应用程序的线程称为主线程,额外创建的线程称为工作线程 。 一般在主线程里创建工作线程,井调用 start()开始执行工作线程的任务 。 start()会在 内 部调用 run()函数,进入工作线程的事件循环,在 run()函数里调用 exit()或 quit()可以结束线程的事件循环,或在主线程里调用 terminate() 强制结束线程。
公共函数部分:
那我们开始写一个小工程吧。
先看下运行的图吧:
页面布局如下:
这获取图片资源:
链接:图片资源 提取码:74g3
提取后记得要加载在项目中。
好的,我们先需要写一个类 QDiceThread 继承与 QThread 如下面:
#ifndef QDICETHREAD_H
#define QDICETHREAD_H
#include
class QDiceThread :public QThread
{
Q_OBJECT
private:
int m_seq=0;//掷骰子次数序号
int m_diceValue;//骰子点数
bool m_Paused = true; //掷一次骰子
bool m_stop=false; //停止线程
protected:
void run() Q_DECL_OVERRIDE; //线程任务,重载run函数
public:
QDiceThread();
void diceBegin(); //掷一次骰子
void dicePause(); //暂停
void stopThread(); //结束线程
signals:
void newValue(int seg,int diceValue); //产生新点数的信号 由主线程的槽函数响应
};
#endif // QDICETHREAD_H
对应的cpp:
#include "qdicethread.h"
#include
QDiceThread::QDiceThread()
{
}
void QDiceThread::run()
{
//线程任务
m_stop = false; //启动线程 m_stop=false
m_seq = 0; //掷骰子次数
qsrand(uint(QTime::currentTime().msec())); //随机数初始化,qsrand是线程安全的
while (!m_stop) {
if(!m_Paused)
{
m_diceValue = qrand(); //获取随机数
m_diceValue = (m_diceValue % 6) +1;
m_seq++;
emit newValue(m_seq,m_diceValue); //发送信号
}
msleep(500); //线程休眠500ms
}
// 在 m_stop==true时结束线程任务
quit(); //相当于 exit(0),退出线程的事件循环
}
void QDiceThread::diceBegin()
{
//开始掷骰子
m_Paused = false;
}
void QDiceThread::dicePause()
{
//暂停掷骰子
m_Paused = true;
}
void QDiceThread::stopThread()
{
//停止线程
m_stop = true;
}
如果你编译过程中出现下面错误,可能是你在创建这个类的时候,没有选择继承 Q_OBJECT:
解决方案:
解决方案与错误分析
如果没有我们继续:
这个是dialog.h 文件:
#ifndef DIALOG_H
#define DIALOG_H
#include
#include "qdicethread.h"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
private:
QDiceThread threadA;
protected:
void closeEvent(QCloseEvent *event);
public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog();
private slots:
//自定义槽函数
void onthreadA_started();
void onthreadA_finished();
void onthreadA_newValue(int seq, int diceValue);
void on_btnStartThread_clicked();
void on_btnDiceBegin_clicked();
void on_btnDiceEnd_clicked();
void on_btnStopThread_clicked();
void on_btnClear_clicked();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
这个是dialog.cpp 文件:
#include "dialog.h"
#include "ui_dialog.h"
void Dialog::closeEvent(QCloseEvent *event)
{
//关闭窗口 并退出程序
if(threadA.isRunning())
{
threadA.stopThread();
threadA.wait();
}
event->accept();
}
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()
{
delete ui;
}
void Dialog::onthreadA_started()
{
//线程started()信号的响应槽函数
ui->LabA->setText("Thread 状态: thread started");
}
void Dialog::onthreadA_finished()
{
//线程的 finished()信号的响应槽函数
ui->LabA->setText("Thread状态:thread finished");
}
void Dialog::onthreadA_newValue(int seq, int diceValue)
{
//QDiceThread的newValue()信号的响应槽函数,显示骰子次数和点数
QString str = QString::asprintf("第 %d 次掷骰子,点数为:%d",seq,diceValue);
ui->plainTextEdit->appendPlainText(str);
QPixmap pic;//图片显示
QString filename = QString::asprintf(":/dice/images/d%d.jpg",diceValue);
pic.load(filename);
ui->LabPic->setPixmap(pic);
}
void Dialog::on_btnStartThread_clicked()
{
//开始线程
threadA.start(); //开始线程,会执行重载的run 函数
ui->btnStartThread->setEnabled(false);
ui->btnStopThread->setEnabled(true);
ui->btnDiceBegin->setEnabled(true);
ui->btnDiceEnd->setEnabled(false);
}
void Dialog::on_btnDiceBegin_clicked()
{
//开始 掷骰子按钮
threadA.diceBegin();
ui->btnDiceBegin->setEnabled(false);
ui->btnDiceEnd->setEnabled(true);
}
void Dialog::on_btnDiceEnd_clicked()
{
//暂停 掷骰子按钮
threadA.dicePause();
ui->btnDiceBegin->setEnabled(true);
ui->btnDiceEnd->setEnabled(false);
}
void Dialog::on_btnStopThread_clicked()
{
//结束线程
threadA.stopThread();
threadA.wait();
ui->btnStartThread->setEnabled(true);
ui->btnStopThread->setEnabled(false);
ui->btnDiceBegin->setEnabled(false);
ui->btnDiceEnd->setEnabled(false);
}
void Dialog::on_btnClear_clicked()
{
//清空文本 按钮
ui->plainTextEdit->clear();
}
大部分功能都有中文解释了,请慢慢理解,可以看这本书,对比来。
希望大家多多学习进步。
作者:比卡丘不皮