需求:当UI线程发送信号给该线程后,该线程则执行播放音频的任务(arm开发板使用脚本播放音频)
一,创建线程类
slot_play_music函数是主线程发送给子线程的信号而执行的槽函数
线程中必须声明Q_OBJECT并继承QThread类,然后重新run方法
#ifndef SOUNDTHREAD_H
#define SOUNDTHREAD_H
#include <QObject>
#include <QThread>
class SoundThread : public QThread
{
Q_OBJECT
public:
SoundThread();
private:
QString soudPath =""; //音频文件路径
public slots:
void slot_play_music(QString path);
protected:
void run() override;
};
#endif // SOUNDTHREAD_H
二,链接主线程和子线程的信号和槽,并执行线程的sart方法
线面的方法执行在UI线程,其中sig_play_music是上面的槽函数对应的信号函数
start线程后调用 emit 发射这个信号给子线程
SoundThread *soundThread = new SoundThread();
connect(soundThread, SIGNAL(finished()), soundThread, SLOT(deleteLater()));
connect(this, SIGNAL(sig_play_music(QString)), soundThread, SLOT(slot_play_music(QString)));
soundThread->start();
emit sig_play_music(MySoundUtil::WELCOME_START);
注意,线程的创建要用new SoundThread方法 而不能用SoudThread soundthread; 不然主线程执行完这些方法后 soundthread会被回收,从而出现错误,如果你的线程只是使用一次,可以使用这种方式,但我们的线程是死循环不停的执行任务,所以要用new SoundThread();这种方式
三,在线程中实现run方法,执行发播放声音的方法, 下面的代码run中开启了一个子线程,目的是保持线程一直处于运行状态,这样就可以一直让该线程执行某个任务,exec()的目的是为了让线程处于接收信号的状态,并进行阻塞,如果调用这个方法,线程就不会收到主线程的信号。
然后执行play播放声音的耗时任务。
当收到主线程的信号后,执行exit(),退出信号接收状态,exec()的阻塞状态就会解除,执行完任务进行下一次阻塞
#include "soundthread.h"
#include "com/utils/mysoundutil.h"
#include <QDebug>
SoundThread::SoundThread()
{
}
void SoundThread::slot_play_music(QString path)
{
soudPath = path;
qDebug() << "收到播放信号:" << path;
exit();//信号来之后则退出事件循环接收状态
}
void SoundThread::run()
{
while(1)
{
exec();//事件循环接收状态,等待接收信号,阻塞当前线程
MySoundUtil::play(soudPath);
}
}