用Qt 也一年多了,工作过程中线程是少不了的,以前项目中都是继承QThread 然后重载run()函数。而且一直喜欢这种方法。后来发现QT 还有个方法就是MoveThread 不过一直不喜欢用。也有看网上其他人的使用过程,总是喜欢把继承的Qobject类的槽函数跟Qthread的started信号相关联(这句话纯吐槽)。 既然有多种方法实现线程,还是学习一下怎么使用比较好。这里记录一下用法,以便自己后面项目中用到。
创建项目添加一个新的类,注意继承QObect。 定义一个QThread的成员变量。定义自己处理问题的槽函数。如果你槽函数的实现是个while,启动方法可以用我吐槽的那种方法(哈哈,突然想到的)。
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QThread>
class myThread : public QObject
{
Q_OBJECT
public:
explicit myThread(QObject *parent = nullptr);
bool quitThread();
signals:
public slots:
void firstSlot();
void secondSlot();
void threeSlot();
private:
QThread m_work;
};
#endif // MYTHREAD_H
*.cpp的实现,在构造函数里调用moveToThread(), 同时注意要调用start()。这里构造函数实际上还是属于它依赖的函数的。
#include "mythread.h"
#include <QDebug>
myThread::myThread(QObject *parent) : QObject(parent)
{
qDebug() << "befor thread id " << QThread::currentThreadId();
this->moveToThread(&m_work);
m_work.start();
connect(&m_work, SIGNAL(started()), this, SLOT(firstSlot()));
qDebug() << "after thread id " << QThread::currentThreadId();
}
void myThread::firstSlot()
{
qDebug() << "first current id " << QThread::currentThreadId();
}
void myThread::secondSlot()
{
qDebug() << "second current id " << QThread::currentThreadId();
}
void myThread::threeSlot()
{
qDebug() << "three current id " << QThread::currentThreadId();
}
bool quitThread()
{
m_work.quit();
return m_work.wait();
}
接下来就是调用了,
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <mythread.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
private:
Ui::MainWindow *ui;
myThread* my_thread;
};
#endif // MAINWINDOW_H
这里要说明一下,1 如果在主线程中直接调用myThread的槽函数,槽函数在主线程中执行。2.connect关联线程槽函数的时候
第三个参数如果是Qt::DirectConnection, 槽函数在发出信号的线程中执行,这里是主线程。
Qt::DirectConnection(直接连接)
当信号发射时,槽函数将直接被调用,无论槽函数所属对象在哪个线程,槽函数都在发射信号的线程内执行
Qt::QueuedConnection(队列连接)
当控制权回到接受者所依附线程的事件循环时,槽函数被调用,槽函数在接收者所依附线程执行。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
my_thread = new myThread();
connect(ui->pushButton, SIGNAL(clicked()), my_thread, SLOT(firstSlot()), Qt::DirectConnection);
connect(ui->pushButton_2, SIGNAL(clicked()), my_thread, SLOT(secondSlot()), Qt::QueuedConnection);
connect(ui->pushButton_3, SIGNAL(clicked()), my_thread, SLOT(threeSlot()));
qDebug() << "main thread id " << QThread::currentThreadId();
}
MainWindow::~MainWindow()
{
// 经过网络朋友的提醒,这里增加一下线程的退出。当然如果myThread槽函数里有while 还有优先退出while。
my_thread->quitThread();
delete my_thread;
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
my_thread->firstSlot();
}
void MainWindow::on_pushButton_2_clicked()
{
my_thread->secondSlot();
}
void MainWindow::on_pushButton_3_clicked()
{
my_thread->threeSlot();
}
好了,就到这里吧。