QThread::CurrentThread是指的当前函数调用者者所在的线程
this->thread是指的当前对象所在的线程(对象创建出来的时候所在的线程)
Qt文档说明
CurrentThread返回一个指向管理当前执行线程的QThread的指针
thread返回对象所在的线程
这两个函数所说的并不是一回事
如果想要将一个对象保证在主线程中处理一些事情,应该是使用this->thread来判断对象所处的线程,而并不是使用QThread::CurrentThread来判断对象所处的线程
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "mythread.h"
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
signals:
void sigTest();
private:
Ui::MainWindow *ui;
MyThread *m_pThread;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_pThread = new MyThread();
m_pThread->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
m_pThread->m_flag = ui->checkBox->checkState();
}
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
class MyThread:public QThread
{
Q_OBJECT
public:
MyThread();
bool m_flag = false;
protected:
void run();
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include "singleclass.h"
#include <QDebug>
MyThread::MyThread() {}
void MyThread::run()
{
qDebug()<<"子线程:"<<QThread::currentThread();
while(true)
{
QThread::msleep(100);
if(m_flag)
{
SingleClass::getInstance()->Test();
m_flag = false;
}
}
}
singleclass.h 测试对象
#ifndef SINGLECLASS_H
#define SINGLECLASS_H
#include <QObject>
class SingleClass : public QObject
{
Q_OBJECT
public:
static SingleClass* getInstance();
void Test();
public slots:
void slotTest();
signals:
void sigTest();
private:
explicit SingleClass();
};
#endif // SINGLECLASS_H
singleclass.cpp
#include "singleclass.h"
#include <QThread>
#include <QDebug>
#include <QApplication>
SingleClass::SingleClass()
{
connect(this,&SingleClass::sigTest,this,&SingleClass::slotTest,Qt::BlockingQueuedConnection);
}
SingleClass* SingleClass::getInstance()
{
static SingleClass instance;
return &instance;
}
void SingleClass::Test()
{
qDebug()<<"Test";
qDebug()<<"currentThread:"<<QThread::currentThread();
qDebug()<<"this线程"<<this->thread();
if(this->thread() != qApp->thread())
{
qDebug()<<"this 所在的线程非主线程,移动到主线程中";
moveToThread(qApp->thread());
}
qDebug()<<"after:";
qDebug()<<"currentThread"<<__FUNCTION__<<QThread::currentThread();
qDebug()<<"this 线程"<<this->thread();
emit sigTest();
}
void SingleClass::slotTest()
{
qDebug()<<"slotTest";
qDebug()<<"信号发出者所在的线程:"<<sender()->thread();
qDebug()<<"currentThread"<<__FUNCTION__<<QThread::currentThread();
qDebug()<<"this 线程"<<this->thread();
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <SingleClass.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//如果在这里调用那么对象所处的线程直接就是主线程
// SingleClass::getInstance();
qDebug()<<"主线程:"<<QThread::currentThread();
MainWindow w;
w.show();
return a.exec();
}
界面
点击按钮之后输出
主线程: QThread(0x20d70e06b00)
子线程: MyThread(0x20d70e7db40)
Test
currentThread: MyThread(0x20d70e7db40)
this线程 MyThread(0x20d70e7db40)
this 所在的线程非主线程,移动到主线程中
after:
currentThread SingleClass::Test MyThread(0x20d70e7db40)
this 线程 QThread(0x20d70e06b00)
slotTest
信号发出者所在的线程: QThread(0x20d70e06b00)
currentThread SingleClass::slotTest QThread(0x20d70e06b00)
this 线程 QThread(0x20d70e06b00)
可以看到SingleClass这个类对象是在子线程中的,CurrentThread线程是子线程
之后调用moveToThread之后singClass类对象是移动到了主线程,所以通过使用connect(this,&SingleClass::sigTest,this,&SingleClass::slotTest,Qt::BlockingQueuedConnection);
因为是队列连接,所以槽函数是在槽函数所在的线程中执行的
之后发出信号之后,slotTest就是在主线程中执行了
注意:信号是在子线程中发出,槽函数是在主线程执行的
信号发出的线程并不是指的信号所在的对象的线程,而是发出信号时候的被调用函数的所在的线程