• 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]);

    总结

    善于总结,多进一步。

  • 相关阅读:
    记一次乐观锁并发场景下遇到的问题
    postman查询数据库-Xmysql
    电子学会2021年6月青少年软件编程(图形化)等级考试试卷(一级)答案解析
    工业互联网网络体系安全防护研究
    【html】利用生成器函数和video元素,取出指定时间的视频画面
    LLM面面观之LLM复读机问题及解决方案
    mac 查看音频信息
    1.0、C语言数据结构 ——初识数据结构和算法
    从四个角度全面认识 ChatGPT
    【计算机毕业设计】家政服务平台
  • 原文地址:https://blog.csdn.net/m0_51988927/article/details/125536639