1.摘要
Qt实现多线程机制主要有两种方法,一是继承QThread重写Run函数,另一种是创建一个继承QObject的类在其中movethread到另一个线程中。
1.方法一实现多线程
用一个简单例子说明使用继承QThread重写Run函数实现多线程。
新建一个工程,添加一个
Thread类继承QThread
头文件:
#ifndef THREAD_H
#define THREAD_H
#include <QThread>
#include <QMutex>
class Thread:public QThread
{
Q_OBJECT
public:
Thread();
void setMessage(const QString &message);
void stop();
protected:
void run();
private:
QString messageStr;
volatile bool stopped;
QMutex mutex;
};
#endif // THREAD_H
CPP文件:
#include "thread.h"
#include <QDebug>
Thread::Thread()
{
stopped=false;
}
void Thread::setMessage(const QString &message)
{
messageStr=message;
}
void Thread::run()
{
forever
{
if(stopped)
{
stopped=false;
break;
}
qDebug()<<messageStr;
}
qDebug()<<endl;
}
void Thread::stop()
{
stopped=true;
}
dialog界面:
dialog 头文件:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include "thread.h"
#include <QCloseEvent>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
protected:
void closeEvent(QCloseEvent *event);
private slots:
void on_btnStartA_clicked();
void on_btnStartB_clicked();
private:
Thread threadA;
Thread threadB;
private:
Ui::Dialog *ui;
};
#endif // DIALOG_Hdialog cpp文件:
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
threadA.setMessage("A");
threadB.setMessage("B");
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_btnStartA_clicked()
{
if(threadA.isRunning())
{
threadA.stop();
ui->btnStartA->setText(tr("Start A"));
}
else
{
threadA.start();
ui->btnStartA->setText(tr("Stop A"));
}
}
void Dialog::on_btnStartB_clicked()
{
if(threadB.isRunning())
{
threadB.stop();
ui->btnStartB->setText(tr("Start B"));
}
else
{
threadB.start();
ui->btnStartB->setText(tr("Stop B"));
}
}
void Dialog::closeEvent(QCloseEvent *event)
{
threadA.stop();
threadB.stop();
threadA.wait();
threadB.wait();
event->accept();
}
这里主要通过点击按钮一个线程循环输出A,一个线程循环输出B。
3.方法二实现多线程
Qt4.8之后,官方建议使用该方法实现多线程,这个方法也比方法一灵活。
新建一个工程添加
DBMoveToThread类继承自QObject
头文件:
#ifndef DBMOVETOTHREAD_H
#define DBMOVETOTHREAD_H
#include <QObject>
#include <QDebug>
#include <QThread>
class DBMoveToThread:public QObject
{
Q_OBJECT
public:
explicit DBMoveToThread(QObject *parent=0);
public slots:
void callWork();
void slotWork1();
void slotWork2();
private:
QThread *thread;
};
#endif // DBMOVETOTHREAD_H
CPP文件:
#include "dbmovetothread.h"
DBMoveToThread::DBMoveToThread(QObject *parent):
QObject(parent)
{
thread=new QThread;
this->moveToThread(thread);
thread->start();
}
void DBMoveToThread::callWork()
{
qDebug()<<"callWork"<<QThread::currentThreadId();
}
void DBMoveToThread::slotWork1()
{
qDebug()<<"slotWork1"<<QThread::currentThreadId();
}
void DBMoveToThread::slotWork2()
{
qDebug()<<"slotlWork2"<<QThread::currentThreadId();
}dilalog界面
头文件:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include "dbmovetothread.h"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
private:
DBMoveToThread *work;
DBMoveToThread *work1;
DBMoveToThread *work2;
private:
void maincall();
};
#endif // DIALOG_H
Cpp文件:
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
work=new DBMoveToThread;
work1=new DBMoveToThread;
work2=new DBMoveToThread;
connect(ui->pushButton,SIGNAL(clicked()),work,SLOT(slotWork1()),Qt::QueuedConnection);
connect(ui->pushButton_2,SIGNAL(clicked()),work1,SLOT(slotWork1()),Qt::QueuedConnection);
connect(ui->pushButton_3,SIGNAL(clicked()),work2,SLOT(slotWork2()),Qt::QueuedConnection);
}
void Dialog::maincall()
{
work->callWork();
}
Dialog::~Dialog()
{
delete ui;
}