QT 项目 线程信号切换 举例
需求:一个线程播放音乐,我在其他任意线程可以调用这个播放音乐的方法,并且播放音乐的方法已知是在播放音乐这个线程,这样就就可以单线程播放音乐。
实现:
1,头文件
class Play_Music_Manager : public QObject
{Q_OBJECT
public:bool is_playing =false;static const int IF_PLAYING_DROP; //如果正在播放其他声音则丢弃现在的,播播放static const int IF_PLAYING_WAIT; //如果正在播放其他声音则等待,,所以要继续发送public:Play_Music_Manager();Play_Music_Manager(MainWindow * mw);void play_music_name(string &music,int type);public slots:void slot_play_music_name(string music);signals:void sig_play_music_name(string music);};
CPP
Play_Music_Manager::Play_Music_Manager()
{}Play_Music_Manager::Play_Music_Manager(MainWindow *mw)
{p_mw = mw;
}//可以在任意线程调用这个方法
void Play_Music_Manager::play_music_name(string &music,int type)
{if(is_playing){if(type == IF_PLAYING_DROP){//如果是这种模式则丢弃,不播放}if(type == IF_PLAYING_WAIT){//如果是这种规则,则需要等待emit sig_play_music_name(music);}}else{emit sig_play_music_name(music);}
}void Play_Music_Manager::slot_play_music_name(string music)
{is_playing = true;//TODO //在这里可以实现播放音乐的方法is_playing = false;
}
创建线程
//声音管理线程,防止在多个线程播放声音,概率性出现同时播放的抢占问题QThread *playMusicTh = new QThread;musicManager = new Play_Music_Manager(this);musicManager->moveToThread(playMusicTh);connect(musicManager, SIGNAL(sig_play_music_name(string)), musicManager, SLOT(slot_play_music_name(string)));connect(playMusicTh, SIGNAL(finished()), playMusicTh, SLOT(deleteLater()));playMusicTh->start();
调用方式
musicManager->play_music_name();
说明:
可以看到我们创建了线程Play_Music_Manager 并且我们绑定信号槽的时候,信号和槽函数都在当前线程,然后我们在这个线程中实现了一个方法play_music_name,只要我们在任何地方或者县城里调用 musicManager->play_music_name(); 方法,都会发送一个信号给这个线程,让这个线程播放音乐,这样就不会出现多线程的问题了。注意:play_music_name 方法还是在哪个线程调用的就会在哪个线程中执行,关键是这个方法里调用了信号发送的方法,会执行槽函数 slot_play_music_name,这个方法才是在线程中实现的方法,而且不会出现多线程的问题