Qt线程的实现:子类化QThread V.S. 对象moveToThread

本文介绍了在Qt中使用线程的两种常见方法:子类化QThread和使用moveToThread。通过示例代码详细展示了如何创建Worker类来执行特定任务,以及如何将对象移动到指定线程中进行操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

子类化QThread

    这个用法很简单,首先创建一个Worker类继承QThread,重写run()函数即可。常见的用法伪代码如下:

// 定义线程
class Worker : public QThread{
	
protected:
	void run(){
		
		// do something
	}	
}

// 使用线程
Worker *worker = new Worker;
worker->start(); // run函数开始运行

这样写的线程有以下缺点:

1、线程中的对象必须在run函数中创建

2、线程无法接收信号,只能发送信号

对象moveToThread

    顾名思义是将一个对象移动到某个线程中去运行。大概的用法流程是创建一个Worker类继承QObject,定义一些你想做的槽函数,然后new一个QThread对象,并把Worker的实例化move到这个线程中去,连接好相应的信号和槽就可以在线程中跑起来了。以下给出一个用法示例代码及其运行结果:

Worker.h

#pragma once
#include <QObject>
#include <qDebug>

class Worker : public QObject
{
	Q_OBJECT

public:
	Worker();
	~Worker();

public slots:
	void EatApple();
	void EatBanana();
	void EatOrange();

private:

};

Worker.cpp

#include "Worker.h"
#include <QThread>

Worker::Worker()
	: QObject()
{
}

Worker::~Worker()
{
}

void Worker::EatApple(){

	qDebug() << "Apple" << QThread::currentThreadId(); 
}
void Worker::EatBanana(){

	qDebug() << "Banana" << QThread::currentThreadId();
}
void Worker::EatOrange(){

	qDebug() << "Orange" << QThread::currentThreadId();
}

QtMoveToThread.h

#pragma once

#include <QtWidgets/QWidget>
#include "ui_QtMoveToThread.h"
#include "Worker.h"

class QtMoveToThread : public QWidget
{
    Q_OBJECT

public:
    QtMoveToThread(QWidget *parent = Q_NULLPTR);

public slots:
	void EatApple();
	void EatBanana();
	void EatOrange();

private:
    Ui::QtMoveToThreadClass ui;
	Worker *worker;
};

QtMoveToThread.cpp

#include "QtMoveToThread.h"
#include <QThread>

QtMoveToThread::QtMoveToThread(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);

	worker = new Worker;
	connect(ui.bAppleWorker, SIGNAL(clicked()), worker, SLOT(EatApple()));
	connect(ui.bBananaWorker, SIGNAL(clicked()), worker, SLOT(EatBanana()));
	connect(ui.bOrangeWorker, SIGNAL(clicked()), worker, SLOT(EatOrange()));
	connect(ui.bAppleMain, SIGNAL(clicked()), this, SLOT(EatApple()));
	connect(ui.bBananaMain, SIGNAL(clicked()), this, SLOT(EatBanana()));
	connect(ui.bOrangeMain, SIGNAL(clicked()), this, SLOT(EatOrange()));

	QThread *eatTsk = new QThread;	// New 一个QThread
	worker->moveToThread(eatTsk);	// worker实例化 move进去
	eatTsk->start();
}

void QtMoveToThread::EatApple(){

	worker->EatApple(); // 主线程调用worker
}
void QtMoveToThread::EatBanana(){

	worker->EatBanana(); // 主线程调用worker
}
void QtMoveToThread::EatOrange(){

	worker->EatOrange(); // 主线程调用worker
}

运行结果

和子类化QThread对比

    优点是克服了重写run的缺点,比较灵活简洁,但是不能在线程里面实现常驻任务(死循环的任务)。

总结

    1、常驻任务使用继承QThread重写run

    2、其他的一次性任务或者间歇性任务尽量都用moveToThread

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值