data 2018/10/24 add by WJB
在qt中使用多线程,以前的方法创建一个自己的thread的类,继承与QThread,然后重写run方法,从而实现多线程。交新版本的qt出现了movetoThread方法实现多线程。该方法由于使用起来比较灵活,得到广发应用;
首相要创建一个继承QObject的类(myobject),然后new一个Qthread,并把创建的myobject类movetothread到创建好的子线程中,然后start子线程,这样就实现了一个子线程。主线程通过发送信号,调用myobject中的方法,从而实现在子线程中的计算。
实例代码如下:
MyThread.h————————————————————————————————————————————————
#pragma once
#include <QObject>
#include <QDebug>
#include <QThread>
class MyThread :public QObject
{
Q_OBJECT
public:
MyThread();
~MyThread();
public slots:
void first();
void second();
void three();
signals:
void sig_sendfirst();
void sig_sendsecond();
void sig_sendThird();
};
MyThread.cpp
#include "MyThread.h"
MyThread::MyThread()
{
}
MyThread::~MyThread()
{
}
void MyThread::first()
{
qDebug() <<"first"<< QThread::currentThreadId();
sig_sendfirst();
}
void MyThread::second()
{
qDebug() << "second" << QThread::currentThreadId();
sig_sendsecond();
}
void MyThread::three()
{
qDebug() << "three" << QThread::currentThreadId();
sig_sendThird();
}
MovetoThreadTest.h
#include <QtWidgets/QMainWindow>
#include "ui_movetothreadtest.h"
#include "MyThread.h"
class MovetoThreadTest : public QMainWindow
{
Q_OBJECT
public:
MovetoThreadTest(QWidget *parent = 0);
~MovetoThreadTest();
public slots:
void onSelfPushed();
void onExitPushed();
void slot_myfirst();
void slot_mysecond();
void slot_mythird();
void slot_recivefirst();
void slot_recivesecond();
void slot_recivethird();
signals:
void sig_firt();
void sig_second();
void sig_third();
private:
Ui::MovetoThreadTestClass ui;
MyThread * m_pMyThread;
};
MovetoThreadTest.cpp
#include "movetothreadtest.h"
MovetoThreadTest::MovetoThreadTest(QWidget *parent)
: QMainWindow(parent)
{
qDebug() << "main" << QThread::currentThreadId();
ui.setupUi(this);
MyThread* m_pMyThread = new MyThread;
QThread *thread = new QThread;
m_pMyThread->moveToThread(thread);
thread->start();
connect(thread, SIGNAL(started()), m_pMyThread, SLOT(first()));
//用不同的法师调用mythread的方法
connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(slot_myfirst()), Qt::AutoConnection);
connect(ui.pushButton_2, SIGNAL(clicked()), this, SLOT(slot_mysecond()), Qt::QueuedConnection);
connect(ui.pushButton_3, SIGNAL(clicked()), m_pMyThread, SLOT(three()), Qt::QueuedConnection);
connect(this, SIGNAL(sig_firt()), m_pMyThread, SLOT(first()), Qt::QueuedConnection);
connect(ui.pushButton_4, SIGNAL(clicked()), this, SLOT(onSelfPushed()));
connect(ui.pushButton_5, SIGNAL(clicked()), this, SLOT(onExitPushed()));
//mythread 发出信号
connect(m_pMyThread, SIGNAL(sig_sendfirst()), this, SLOT(slot_recivefirst()), Qt::QueuedConnection);
connect(m_pMyThread, SIGNAL(sig_sendsecond()), this, SLOT(slot_recivesecond()), Qt::QueuedConnection);
connect(m_pMyThread, SIGNAL(sig_sendThird()), this, SLOT(slot_recivethird()));
}
MovetoThreadTest::~MovetoThreadTest()
{
}
void MovetoThreadTest::onExitPushed()
{
qDebug() << "onExitPushed" << QThread::currentThreadId();
}
void MovetoThreadTest::slot_myfirst()
{
qDebug() << "slot_myfirst" << QThread::currentThreadId();
emit sig_firt();
}
void MovetoThreadTest::slot_mysecond()
{
qDebug() << "slot_mysecond" << QThread::currentThreadId();
m_pMyThread->second();
}
void MovetoThreadTest::slot_mythird()
{
}
void MovetoThreadTest::slot_recivefirst()
{
qDebug() << "slot_recivefirst" << QThread::currentThreadId();
}
void MovetoThreadTest::slot_recivesecond()
{
qDebug() << "slot_recivesecond" << QThread::currentThreadId();
}
void MovetoThreadTest::slot_recivethird()
{
qDebug() << "slot_recivethird" << QThread::currentThreadId();
}
void MovetoThreadTest::onSelfPushed()
{
qDebug() << "onExitPushed" << QThread::currentThreadId();
}
MovetoThreadTest.cpp 中用到了窗体中的几个按钮,在如用代码是首相创建一个窗体,在窗体添加按钮,然后跟据按钮的名字进行连接即可;
主线程如果要在子线程中运行计算必须通过发信号的方式调用,或者通过控件的信号;需要说明在创建连接时如果第五的参数为DirectConnection时,调用的槽函数是在主线程中运行;如果想通过子线程向主线程调用方法,也必须通过发信号的方式触发主线程的函数。