• Qt笔记——多线程


    这个例子是,点击开始按钮,数字累加,点击停止按钮,数字不动。

    1,新建一个类,里面是子线程的内容

    #ifndef MYTHREAD_H
    #define MYTHREAD_H
    
    #include <QObject>
    
    class MyThread : public QObject
    {
        Q_OBJECT
    public:
        explicit MyThread(QObject *parent = nullptr);
    
        //线程处理函数
        void myTimeout();
        void setFlag(bool flag = false);
    signals:
        void mySignal();
    
    public slots:
    
    private:
        bool isStop;
    };
    
    #endif // MYTHREAD_H
    #include "mythread.h"
    #include <QThread>
    #include <QDebug>
    MyThread::MyThread(QObject *parent) : QObject(parent)
    {
        isStop = false;
    }
    
    void MyThread::myTimeout()
    {
        while(isStop == false)
        {
            QThread::sleep(1);
            emit mySignal();
            qDebug()<<"子线程号: "<<QThread::currentThread();
            if(isStop == true)
            {
                break;
            }
        }
    }
    
    void MyThread::setFlag(bool flag)
    {
        isStop = flag;
    }

    2,主线程中创建QTread 对象,然后将子线程类通过moveToThread()中来

    并且不直接调用子程序(子线程),通过主程序发出一个信号,然后子程序接受到信号,开始运行

    #ifndef MYWIDGET_H
    #define MYWIDGET_H
    
    #include <QWidget>
    #include "mythread.h"
    #include <QDebug>
    namespace Ui {
    class MyWidget;
    }
    
    class MyWidget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit MyWidget(QWidget *parent = 0);
        ~MyWidget();
        void dealSignal();
        void dealClose();
    
    signals:
        void startThread();//启动子线程
    
    private slots:
        void on_startBtn_clicked();
    
        void on_stopBtn_clicked();
    
    private:
        Ui::MyWidget *ui;
        MyThread *myT;
        QThread *thread;
    };
    
    #endif // MYWIDGET_H
    #include "mywidget.h"
    #include "ui_mywidget.h"
    #include <QThread>
    
    MyWidget::MyWidget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::MyWidget)
    {
        ui->setupUi(this);
    
        //动态分配空间,不能指定父对象
        myT = new MyThread;
        //创建子线程
        thread = new QThread(this);
    
        //把自定义线程加入到子线程中
        myT->moveToThread(thread);
        connect(myT,&MyThread::mySignal,this,&MyWidget::dealSignal);
        qDebug()<<"主线程号: "<<QThread::currentThread();
        connect(this,&MyWidget::startThread,myT,&MyThread::myTimeout);
        connect(this,&MyWidget::destroyed,this,&MyWidget::dealClose);
    
        //线程处理函数内部,不允许操作图形界面
    
        //connect()第五个参数的作用,连接方式:默认,队列,直接
        //多线程才有意义
        //默认的时候,如果是多线程,默认使用队列,如果是单线程,默认是用直接方式
        //队列:槽函数所在线程和接受者一样
        //直接:槽函数所在线程和发送者一样
    
    }
    
    void MyWidget::dealClose()
    {
        on_stopBtn_clicked();
        delete myT;
    }
    
    void MyWidget::dealSignal()
    {
        static int i = 0;
        i++;
        ui->lcdNumber->display(i);
    }
    
    MyWidget::~MyWidget()
    {
        delete ui;
    }
    
    void MyWidget::on_startBtn_clicked()
    {
        if(thread->isRunning() == true)
        {
            return;
        }
        //启动线程,但是没有启动线程
        thread->start();
        myT->setFlag(false);
        //不能直接调用线程处理函数,直接调用导致线程处理函数和主线程在同一个线程
        //myT->myTimeout(); //错的
        //只能通过 signal-slot方式调用
        emit startThread();
    }
    
    void MyWidget::on_stopBtn_clicked()
    {
        if(thread->isRunning() == false)
        {
            return;
        }
        myT->setFlag(true);
        thread->quit();
        thread->wait();
    }
  • 相关阅读:
    洪小瑶学iOS-UINavigationController
    flash模拟苹果菜单原理
    洪小瑶学iOS-NSNotificationCenter 详解
    关于体感互动Airkinect研究《案例篇1》
    AS3 兩點求距離
    右鍵點擊Right Click (Flash Player 11.2 新功能)
    像素级碰撞检测研究
    关于体感互动kinect研究《基础篇》
    部署Pentaho BI服务器到独立Tomcat所碰到的问题总结
    c语言的一个技巧问题
  • 原文地址:https://www.cnblogs.com/dalanjing/p/8849500.html
Copyright © 2020-2023  润新知