QT 实现线程moveToThread(QThread *targetThread)

用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();
}

好了,就到这里吧。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值