当前位置:   article > 正文

QT--线程_qt 线程

qt 线程

提示:本文为学习记录,若有错误,请联系作者,谦虚受教。


前言

去找一个像太阳一样的搭档,帮你晒晒所有的一值不提.


一、QT操作线程

1、通过继承QThread类,重写QThread类的run函数,控制Run函数进行新线程的操作。
2、通过继承QObject类,在新建的类中编写线程操作函数,通过movetothread()函数将新建的类转移到新线程中。

二、继承QThread,重写run()

1.mythread类

mythread.h文件

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QDebug>
 
class MyThread : public QThread
{
public:
    explicit MyThread(){}
 
private:
  void run() override;
private slots:
  void sig_ShowMsg(QString,bool);
 
#endif // MYTHREAD_H

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

mythread.cpp文件

void MyThread::run()
{
//复杂函数的执行
emit sig_ShowMsg("发送成功",true);
}
  • 1
  • 2
  • 3
  • 4
  • 5

2.mainwindow

mainwindow.h文件

//定义线程
MyThread* m_thread;
signals:
    void slt_ShowMsg(QString ,bool );
  • 1
  • 2
  • 3
  • 4

mainwindow.cpp文件

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //声明线程
    m_thread = new MyThread;
    //二者之间通过信号与槽联系
    connect(&m_thread,SIGNAL(sig_ShowMsg(QString,bool)),SLOT(slt_ShowMsg(QString ,bool )));
}
//通过按钮触发线程开启
void MainWindow::on_btnstart_clicked()
{
thread->start();//使用该函数的时候会自动调用run函数
qDebug()<<"main thread: "<< QThread::currentThreadId();
emit sig_start();
}
//通过按钮停止线程
void MainWindow::on_btnclose_clicked()
{
//结束线程
thread->exit();
thread->deleteLater();
emit sig_Close();
}
void MainWindoe::slt_ShowMsg(QString a,bool b)
{
  ui->text->setText(a);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

主线程和子线程之间的联系通过信号与槽。
提示:只有在Run函数中的内容才是在新线程中,其他函数都是在旧的线程中。

三、继承QObject,通过moveToThread()

1.MyObject类

//线程处理对象
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QObject>
#include <QThread>
#include <QDebug>
 
class MyObject : public QObject
{
    Q_OBJECT
public:
    explicit MyObject(QObject *parent = 0): QObject(parent){}
    ~MyObject(){}
 
private slots:
    void Start()//线程处理函数
    {
        qDebug()<<"obj thread: "<<QThread::currentThreadId();
    }
};
 
#endif // MYOBJECT_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在Mainwindow中使用时,

//定义变量
MyObject*   obj;
QThread*    thread;
 
//开始线程
obj = new MyObject;//线程执行对象
thread = new QThread;
obj->moveToThread(thread);//将对象移动到新建立的线程
connect(thread, &QThread::started, obj, &MyObject::Start);//绑定线程的开始信号,线程开始后就会执行obj的Start槽函数
thread->start();
qDebug()<<"main thread: "<<QThread::currentThreadId();
 
//结束线程
thread->exit();
thread->deleteLater();//删除对象
obj->deleteLater();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

使用QObject的方法

  1. 写一个继承QObject的类,对需要进行复杂耗时逻辑的入口函数声明为槽函数。
  2. 此类在旧线程new出来,不能给它设置任何父对象
  3. 同时声明一个QThread,如果不是new,在析构时需要调用QThread::wait(),如果是堆分配的话,可以通过deleteLater让线程自动销毁。
  4. 把obj通过moveToThread方法转移到新线程中,此时object已经在线程中。
  5. 把线程的finished信号和object的deleteLater槽连接,这个信号槽必须连接,否则会内存泄漏。
  6. 正常连接其他信号和槽,通过信号和槽来联系。
  7. 初始化完后调用QThread::start()来启动线程
  8. 在逻辑结束后,调用QThread::quit退出线程的事件循环

使用QObject来实现多线程比用继承QThread的方法更加灵活,整个类都是在新的线程中,通过信号槽和主线程传递数据

四、销毁线程

connect(&m_thread,&QThread::finished ,&obj,&QObject::deleteLater);
  • 1

声明一个QThread,如果不是new,在析构时需要调用QThread::wait(),
如果是堆分配的话,可以通过deleteLater让线程自动销毁。
(堆需要程序员自己手动销毁)

插播:
十进制的显示:
QString test = QString::number(rcvBuf3[5]*256 +rcvBuf3[6]);
QString data = QString::number(rcvBuf3[5]<<8 | rcvBuf3[6]);

总结

善于总结,多进一步。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/104507?site
推荐阅读