Qt--多线程(MovetoThread)

Qt的多线程创建一般有两种方法,一是继承QThread并重写run()函数,二是继承QObject,利用信号槽调用相关函数。第一种方法,在新的线程中只能实现run()函数中的内容,而第二种可以通过movetothread()随意调用自己想用的方法,也可以只用一个类实现多个线程共同工作。

以下是代码:

WorkThread.h文件中代码如下

#ifndef WORKTHREAD_H
#define WORKTHREAD_H

#include <QObject>
#include<QDebug>
#include<QThread>

class WorkThread : public QObject
{
    Q_OBJECT
public:
    explicit WorkThread(QObject *parent = nullptr);

signals:

public slots:
    void work1();   
    void work2();
    void work3();
};

#endif // WORKTHREAD_H

WorkThread.cpp代码如下:

#include "workthread.h"

WorkThread::WorkThread(QObject *parent) : QObject(parent)
{

}

void WorkThread::work1()
{
    qDebug() << QString::fromLocal8Bit("work1的线程为:") << QThread::currentThreadId();
}

void WorkThread::work2()
{
    qDebug() << QString::fromLocal8Bit("work2的线程为:") << QThread::currentThreadId();

}

void WorkThread::work3()
{
    qDebug() << QString::fromLocal8Bit("work3的线程为:") << QThread::currentThreadId();

}

MainWindow.h代码如下

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QThread>
#include"workthread.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    WorkThread *work1;
    WorkThread *work2;
    WorkThread *work3;

    QThread *thread1;
    QThread *thread2;
    QThread *thread3;


};

#endif // MAINWINDOW_H

MainWindow.cpp代码如下

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    work1(nullptr),
    work2(nullptr),
    work3(nullptr)
{
    ui->setupUi(this);
    //三个工作对象
    work1 = new WorkThread;
    work2 = new WorkThread;
    work3 = new WorkThread;

    //三个线程对象
    thread1 = new QThread;
    thread2 = new QThread;
    thread3 = new QThread;

    //移入线程
    work1->moveToThread(thread1);
    work2->moveToThread(thread2);
    work3->moveToThread(thread3);

    //线程开始工作
    thread1->start();
    thread2->start();
    thread3->start();

    //建立信号槽,work1、work2、work3分别为三个ui文件中的三个button
    connect(ui->work1, &QPushButton::clicked, work1, &WorkThread::work1);
    connect(ui->work2, &QPushButton::clicked, work2, &WorkThread::work2);
    connect(ui->work3, &QPushButton::clicked, work3, &WorkThread::work3);

}

MainWindow::~MainWindow()
{
    delete ui;
}

ui文件内容为

 运行程序,分别点击三个按钮,得到如下输出

 由此可见,同一个类中的三个槽函数分别在三个不同的线程中,而继承QThread重写run()函数的方法,只能运行在一个线程中。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Qt5 中的 QObject 类提供了一个名为 moveToThread() 的函数,可以将对象从当前线程移动到另一个线程。这样可以使用多线程来并行处理任务,提高程序的性能。使用 moveToThread() 函数时需要注意,被移动到的线程需要先启动,否则会产生错误。 ### 回答2: Qt5是一个开发跨平台应用程序的框架,其中的多线程技术可以使程序效率更高。Qt5中的多线程模型做了大量的工作来简化一个活动对象(也就是一个线程)在多个线程之间被转移时的代码。其中一种常见的实现方式是使用QThread类。 在Qt5中可以使用QThread类来创建一个线程,从而使主线程和子线程可以并发执行。但是,如果在子线程中访问主线程中的UI控件或者调用主线程中的函数的话,就需要使用Qt5中的MovetoThread机制。因为Qt5默认情况下,只有创建控件的主线程才可以操作该控件,如果在其他线程中修改控件,会导致程序崩溃。 MovetoThread的机制就是将主线程中的控件或者函数移动到子线程中执行,以避免跨线程操作UI控件造成崩溃的问题。具体操作步骤如下: 1. 通过QObject::moveToThread()函数将控件或对象移到新线程中; 2. 创建新线程对象; 3. 将需要在新线程中执行的操作绑定到信号槽上。 需要注意的是: 1. 使用MovetoThread机制时,控件必须继承自QObject,才能使用moveToThread()函数; 2. 通过signal-slot方式通信时,可以使用多种数据类型,如QString、QByteArray等,但是不能传递QWidget类型的对象; 3. 在线程中,应该重写run()函数来定义需要执行的操作,但避免直接修改UI控件; 4. 在线程停止之前,需要通过wait()或quit()减轻其负担。 总之,Qt5的MovetoThread机制可以更好地实现多线程操作,同时克服跨线程操作控件的问题,确保程序的稳定性。 ### 回答3: Qt5的多线程中,MoveToThread是一个非常实用的功能。它可以让一个QObject对象从一个线程移动到另一个线程,从而实现线程的切换。在之前的Qt版本中,多线程操作通常需要在各个线程自己的对象中进行,但是Qt5的扩展使得利用其他线程的对象变得更为容易。 其实Qt5关于多线程MoveToThread功能是通过类QThread的方法moveToThread子类继承QThread可以完成该操作,该类的该方法会将对象加入线程队列,等待目标线程执行。同时需要注意到的是,该方法只能被主线程调用。 使用该功能的目的通常是为了防止UI线程(主线程)被阻塞,因为UI线程负责响应用户输入事件,并显示图形化结果,一旦UI线程被长时间阻塞,那么整个应用程序将会卡住,导致非常不友好的用户体验。这是非常不可接受的,因此我们需要将耗时的操作从UI线程中移除,以允许UI线程响应其他事件。 MoveToThread的程序代码通常如下,可以将需要部署到工作线程的对象定义为堆对象(QPointer)或共享指针(std::shared_ptr),以便在工作线程执行时避免对象的销毁: ``` Worker* worker = new Worker; //需要其他线程执行的对象(必须是QObject的子类) QThread* workerThread = new QThread; //启动工作线程 worker->moveToThread(workerThread); workerThread->start(); ``` 然而,需要注意的是,如果QObject派生类高度依赖于QObject的常规信号槽机制,则应该通过(QMetaObject::invokeMethod)调用该方法,而不能直接从工作线程对该对象调用该方法,使得能够进程线程的切换。 总的来说,Qt5的多线程MoveToThread功能使得程序在实现多线程操作时更为高效、更易于维护,避免了因为长时间阻塞UI线程而导致的应用程序卡顿或死机。但是,在实现该功能时,程序员需要小心处理程序设计,避免其他线程啊阻塞工作线程并确保工作线程的任务安全。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值