前言:
众所周知,Qt的信号槽非常重要,当需要发信号的时候,信号接收方得要接收到信号之后,才能触发槽函数,那么一起来讨论一下多线程情况下,哪些地方需要注意的呢?
场景:
有一个界面主线程,还有一个子线程,使用的是重写run函数的方式
当子线程给主线程发信号,我们知道是可以的收到的
那么反过来,使用主线程给子线程发信号,子线程会收到吗?
如果子线程没有启动事件循环,是不会让对应的槽函数在子线程中运行起来的。
大多数默认的情况下,子线程是启动了事件循环的,但是如果已经结束了子线程的事件循环,就会导致没办法执行子线程中的槽函数。
一些子线程代码: 头文件
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
class MyThread : public QThread
{
Q_OBJECT
public:
MyThread();
signals:
void mySignal();
protected:
void run();
public slots:
void mySlot();
};
#endif // MYTHREAD_H
子线程源文件:
#include "mythread.h"
#include <QDebug>
MyThread::MyThread()
{
}
void MyThread::run()
{
emit mySignal();
qDebug()<<"执行了子线程的run:"<<currentThread();
quit();
qDebug()<<"退出线程事件循环";
exit(0);
}
void MyThread::mySlot()
{
qDebug()<<"触发了run线程的槽";
}
界面相关的代码:
头文件:
#ifndef THREADMAINWINDOW_H
#define THREADMAINWINDOW_H
#include <QMainWindow>
#include "mythread.h"
namespace Ui {
class ThreadMainWindow;
}
class ThreadMainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit ThreadMainWindow(QWidget *parent = 0);
~ThreadMainWindow();
signals:
void mainSignal();
private slots:
void on_pushButton_clicked();
void showMessage();
private:
Ui::ThreadMainWindow *ui;
MyThread *m_thread;
};
#endif // THREADMAINWINDOW_H
源文件:
#include "threadmainwindow.h"
#include "ui_threadmainwindow.h"
#include <QDebug>
ThreadMainWindow::ThreadMainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ThreadMainWindow)
{
ui->setupUi(this);
m_thread = new MyThread;
// connect(m_thread,SIGNAL(mySignal()),this,SLOT(showMessage()));
// connect(this,SIGNAL(mainSignal()),m_thread,SLOT(mySlot()));
// m_thread->start();
}
ThreadMainWindow::~ThreadMainWindow()
{
delete ui;
m_thread->deleteLater();
}
void ThreadMainWindow::on_pushButton_clicked()
{
qDebug()<<"发射主线程的信号";
emit mainSignal();
}
void ThreadMainWindow::showMessage()
{
qDebug()<<"收到了子线程的消息";
}
主函数代码:
#include "threadmainwindow.h"
#include <QApplication>
#include "mythread.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ThreadMainWindow w;
w.show();
MyThread mt;
QObject::connect(&w,SIGNAL(mainSignal()),&mt,SLOT(mySlot()));
//mt.exit();
return a.exec();
}