Qt QThread的moveToThread方法使用

这篇具有很好参考价值的文章主要介绍了Qt QThread的moveToThread方法使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Qt线程简介

从 Qt4.4 版本之后,因为 QThread 的 run 方法创建新线程这样实现与 Qt 设计的理念不符,Qt 主推使用 moveToThread 方法来创建新线程。QThread应该被看做是操作系统线程的接口或控制点,而不应该包含需要在新线程中运行的代码。需要运行的代码应该放到一个QObject的子类中,然后将该子类的对象moveToThread到新线程中。主要操作步骤如下:

  1. 创建一个继承QObject类的对象object,创建一个线程QThread对象thread。
  2. 创建主线程中对象 M 与类对象object链接的信号槽。
  3. 通过类对象object的moveToThread方法将类对象object移动到线程对象thread中。
  4. 调用线程对象thread的start方法,启动线程。
  5. 对象 M 调用信号槽,类对象 obj 在新线程thread中处理数据(调用新线程只能通过信号槽来完成,如果要将类对象 obj 的数据传回给对象 M,可以由 obj 发起对 M 的信号槽)。

具体代码如下:

1:要放入新线程的Worker类

h 文件:

#ifndef WORKER_H
#define WORKER_H

#include <QObject>

/*****************************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @version   1.0
  @date      2021-01-09
  @brief     工人类,主要方法do_something打印工人对象所在线程的id
******************************************************************************************/
class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr);

signals:
    /***************************************************************************
     @author   qiaowei
     @version  1.0
     @date     2021-01-24
     @brief    调用Controller::print_thread方法
    ***************************************************************************/
    void result_ready(const QString& content);

public slots:
    /***************************************************************************
     @author   qiaowei
     @version  1.0
     @date     2021-01-07
     @brief    打印Worker对象所在线程id
    ***************************************************************************/
    void do_something();

};

#endif // WORKER_H

cpp 文件:

#include <QtDebug>
#include <QThread>
#include "worker.h"

Worker::Worker(QObject *parent) : QObject(parent)
{

}

void Worker::do_something()
{
    emit result_ready("Hello");

//    int i(0);
//    while (i < 20) {
//        qDebug() << "I'm working in Worker's thread:" << (quint64) QThread::currentThreadId();
//        ++i;
//    }
    qDebug() << "I'm working in Worker's thread:" << (quint64) QThread::currentThreadId();
}

2:操纵Worker类对象的Controller类

h 文件:

#ifndef CONTROLLER_H
#define CONTROLLER_H

#include <QObject>

QT_BEGIN_NAMESPACE
class Worker;
QT_END_NAMESPACE

/*****************************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @version   1.0
  @date      2021-01-06
  @brief     控制线程创建、启动
******************************************************************************************/
class Controller : public QObject
{
    Q_OBJECT
public:
    explicit Controller(QObject *parent = nullptr);

    ~Controller();

    /***************************************************************************
     @author   qiaowei
     @version  1.0
     @date     2021-01-06
     @brief    将对象worker_移入子线程work_thread_,启动子线程
    ***************************************************************************/
    void move_work_to_thread();

signals:
    /***************************************************************************
     @author   qiaowei
     @version  1.0
     @date     2021-01-07
     @brief    调用worker_::do_something方法
    ***************************************************************************/
    void start_running();

public slots:
    void print_thread() const;

private:
    void setup_connections();

    void print_thread_id() const;

private:
    /***************************************************************************
     @author   qiaowei
     @version  1.0
     @date     2021-01-07
     @brief    子线程
    ***************************************************************************/
    QThread* work_thread_;

    /***************************************************************************
     @author   qiaowei
     @version  1.0
     @date     2021-01-07
     @brief    放入子线程work_thread_的对象worker_
    ***************************************************************************/
    Worker* worker_;
};

#endif // CONTROLLER_H

cpp 文件:

#include <QThread>
#include <QtDebug>
#include "controller.h"

#include "worker.h"

Controller::Controller(QObject *parent) :
    QObject(parent),
    work_thread_(new QThread()),
    worker_(new Worker())
{
    setup_connections();

    print_thread_id();

    move_work_to_thread();
}

Controller::~Controller()
{
    work_thread_->quit();
    work_thread_->wait();

    delete work_thread_;

    if (nullptr == work_thread_) {
        qDebug()<< "nullptr";
    } else {
        work_thread_ = nullptr;
    }
}

void Controller::move_work_to_thread()
{
    worker_->moveToThread(work_thread_);

    // 启动子线程。不启动子线程,worker_对象的方法不会被调用(因为运行的环境没启动)
    work_thread_->start();
}

void Controller::print_thread() const
{
//    int i(0);
//
//    while (i < 20) {
//        print_thread_id();
//        ++i;
//    }
    print_thread_id();
}

void Controller::setup_connections()
{
    connect(this,
            &Controller::start_running,
            worker_,
            &Worker::do_something);

    connect(worker_,
            &Worker::result_ready,
            this,
            &Controller::print_thread);
}

void Controller::print_thread_id() const
{
    qDebug()<< "Controller::Controller = " << (quint64) QThread::currentThreadId();
}

触发线程的ui类

h 文件:

#ifndef CONTROLLER_DIALOG_H
#define CONTROLLER_DIALOG_H

#include <QDialog>

QT_BEGIN_NAMESPACE
class Controller;
QT_END_NAMESPACE

namespace Ui {
class Controller_dialog;
}

/*****************************************************************************************
  @copyright 2013-2020
  @author    qiaowei
  @contact   weiweiqiao@126.com
  @version   1.0
  @date      2021-01-09
  @brief     操作多线程的ui
******************************************************************************************/
class Controller_dialog : public QDialog
{
    Q_OBJECT

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

private:
    void setup_connections();

private:
    Ui::Controller_dialog *ui;

    Controller* controller_;
};

#endif // CONTROLLER_DIALOG_H

cpp 文件:

#include "controller_dialog.h"
#include "ui_controller_dialog.h"

#include "controller.h"

Controller_dialog::Controller_dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Controller_dialog),
    controller_(new Controller())
{
    ui->setupUi(this);

    setup_connections();
    setFixedSize(sizeHint());
}

Controller_dialog::~Controller_dialog()
{
    delete ui;
    delete controller_;
}

void Controller_dialog::setup_connections()
{
    // 启动新线程
    connect(ui->start_button_,
            &QPushButton::clicked,
            controller_,
            &Controller::start_running);

    // 关闭所有窗体,退出程序
    connect(ui->quit_button_,
            &QPushButton::clicked,
            qApp,
            &QApplication::closeAllWindows);
}

界面 ui:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Controller_dialog</class>
 <widget class="QDialog" name="Controller_dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>219</width>
    <height>83</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <layout class="QGridLayout" name="gridLayout">
   <item row="0" column="0">
    <layout class="QHBoxLayout" name="horizontalLayout">
     <item>
      <widget class="QPushButton" name="start_button_">
       <property name="text">
        <string>Start Button</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="quit_button_">
       <property name="text">
        <string>Quit</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

main 文件:

#include <QApplication>

#include "mainwindow.h"
#include "thread_dialog.h"
#include "controller_dialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Controller_dialog d;
    d.show();

    return a.exec();
}

运行结果,打印Print_thread、Worker对象的线程号:

Qt QThread的moveToThread方法使用,Qt&amp;Pyside,C&amp;C++,qt,开发语言,c++

 可以看到打印结果,Worker 对象在线程 9480,主程序入口在线程 5336文章来源地址https://www.toymoban.com/news/detail-630350.html

到了这里,关于Qt QThread的moveToThread方法使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Python之Pyside】如何在pycharm中使用pyside开发编辑Qt ui界面(uic、rcc)

    qtcreator自带designer设计师编辑器,非常好用。 但是我们使用pycharm进行界面开发的时候没有designer,在pycharm中直接双击qt的ui文件会直接进行xml格式的编辑。 要在pycharm中支持双击ui文件打开qtdesigner,我们需要先 在pycharm中添加安装了pyside6的python环境,注意,安装pyqt5不支持,旧

    2024年04月12日
    浏览(29)
  • 13-1_Qt 5.9 C++开发指南_多线程及QThread 创建多线程程序_ThreadSignal

    一个应用程序一般只有一个线程,一个线程内的操作是顺序执行的,如果有某个比较消耗时间的计算或操作,比如网络通信中的文件传输,在一个线程内操作时,用户界面就可能会冻结而不能及时响应。这种情况下,可以创建一个单独的线程来执行比较消耗时间的操作,并与

    2024年02月14日
    浏览(35)
  • QT -- 多线程 —— moveToThread

    视频教程链接: https://www.bilibili.com/video/BV1fL4y1V7QP/?spm_id_from=333.880.my_history.page.clickvd_source=b91967c499b23106586d7aa35af46413 moveToThread函数的功能:给多个任务(比如显示多个界面)各分配一个线程去执行。这样就避免了自定义好多个类继承自QThread类,从而可以避免冗余。 翻译:更改

    2024年01月25日
    浏览(26)
  • qt之movetothread理解

    qt的下线程qthread,每个线程都有自己的事件循环exec。 对象的线程上下文,每个对象都有自己的线程上下文,怎么理解呢,就是该对象在哪个线程创建,其线程上下文就是谁。 每个qobject对象在创建时都有包含线程成员,threaddata,该成员的类型是QThreadData,该成员与qobject对象

    2024年02月09日
    浏览(24)
  • Qt:moveToThread

    该函数属于QObject,因此任何继承于QObject的对象都可以使用该函数。 使用该函数可以减少主线程界面刷新的压力 官方解释: 1: 更改此对象及其子对象的线程相关性。如果对象有父对象,则无法移动该对象。事件处理将在targetThread中继续。 解释:每一个QObject对象都有事件循

    2024年02月12日
    浏览(21)
  • 【QT5-自我学习-线程qThread练习-两种使用方式-1:通过继承线程类来使用-基础样例】

    学习线程其实有一段时间了,当时只是学习,没有实际用起来,最近做的一个qt程序,发现如果不使用线程,那么就会导致界面卡死,这样才体现出线程的实际作用。 发现卡顿的程序就是前几天说到的“【QT调用ST-link-使用QT编写程序-调用ST-LINK_CLI.exe-烧写STM32F4xxx-基础样例】”

    2024年02月11日
    浏览(32)
  • QT学习之旅 - QThread多线程

    其实QT中的thread(线程)是很容易的 首先是主线程 其次是一个程序 通过一个QThread来放入程序 一个简单的线程就实现了 进阶一点: 手动开启关闭线程 添加一个按键,通过 信号和槽 来控制线程使能关闭 Test不变。 现象 是 mainwindow i:99(执行完) 后窗口出现,之后 开启线程 。开启后

    2024年02月16日
    浏览(36)
  • PyCharm下安装配置PySide6开发环境(Qt Designer、PyUIC和PyRCC)

    本篇我们来介绍一下在PyCharm中如何安装和配置PySide6的开发运行环境。 开发PySide6项目,我们可以使用Qt Designer、PyUIC和PyRCC这些好用的外部工具。 Qt Designer是啥东西?简单的来说就是设计Qt界面的辅助开发工具,可以像开发VB那样通过拖拽的方式进行所见即所得的可视化开发G

    2023年04月08日
    浏览(32)
  • 02、Pycharm中配置PyQt/PySide开发工具Qt Designer、PyUIC、PyRcc(详细)

    上一篇文章: 01、Pyqt/PySide6简介及安装方法 PySide6、PyQt5 都是基于Qt 库。Qt库里面有非常强大的图形界面开发库,但是Qt库是C++语言开发的,PySide2、PySide6、PyQt5可以让我们通过Python语言使用Qt https://blog.csdn.net/python_sy/article/details/127425142 目录 前言 一、Qt Designer、PyUic、PyRcc是什么

    2023年04月14日
    浏览(35)
  • PyCharm下安装配置PySide6开发环境(Qt Designer(打开,编辑)、PyUIC和PyRCC)

    python安装路径  pycharm安装路径: python系统变量: pycharm环境变量:   注意:正常安装,并勾选ADD PATH一般会自动配好 用pycharm开发python项目时,使用虚拟环境的好处是: 可以为不同的项目创建不同的python环境,避免了依赖包和版本的冲突。 可以为同一个项目的不同环境(如

    2024年02月11日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包