53黑马QT笔记之Qt下创建新线程之Qt5版本

编程入门 行业动态 更新时间:2024-10-09 08:31:17

53黑马QT笔记之Qt下创建新<a href=https://www.elefans.com/category/jswz/34/1771240.html style=线程之Qt5版本"/>

53黑马QT笔记之Qt下创建新线程之Qt5版本

1 创建新线程步骤:

1)自定义一个类,必须继承于QOject,但函数名可以是任意,不一定为run。
2)创建自定义类对象myT(一般作为主线程的成员)。 不能指定父对象this,因为后面要将该对象移动到QThraead对象。
3)创建QThread类对象thread(一般作为主线程的成员)。
4)将自定义类对象移动到子线程中,自定义类就相当于一个子线程。 myT.movetoThread(thread);
5)启动子线程。 thread.start(); 但与Qt4版本与区别,这里只是启动了线程,线程函数还没启动。
6)启动线程函数,但只能通过信号和槽启动。所以一般是通过按钮启动。
7)以上步骤已经完整创建一个新线程了,但是一般在新线程处理完复杂数据都会发射一个信号,该信号带一个或多个参数,返回给主进程使用。这一点下一篇的线程画图会使用到。

2 Qt5版本解决上两篇程序卡顿问题:

1)自定义类头文件:

#ifndef MYTHREAD_QT5_H
#define MYTHREAD_QT5_H#include <QObject>class MyThread_qt5 : public QObject          //qt4继承的类为QThread
{Q_OBJECT
public:explicit MyThread_qt5(QObject *parent = 0);void dealMsg();                          //线程处理函数void setFlag(bool flag);                 //由于isStop为私有,所以定义公有函数调用signals:isDone();                                //线程处理函数完毕信号private:bool isStop;                             //标志位,用于跳出循环,进而可以在外面改变标志位结束线程public slots:
};#endif // MYTHREAD_QT5_H

2)自定义类.cpp文件:

#include "mythread_qt5.h"
#include<QThread>
#include<QDebug>MyThread_qt5::MyThread_qt5(QObject *parent) : QObject(parent)
{isStop=false;                 //构造时默认为false
}void MyThread_qt5::dealMsg()
{while(false == isStop){QThread::sleep(1);emit isDone();        //每隔一秒发送信号qDebug()<<"子线程号: "<<QThread::currentThread();}}void MyThread_qt5::setFlag(bool fg)
{isStop=fg;                    //默认为false,若有外部传参fg则改变
}

3)主线程头文件:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QThread>
#include"mythread_qt5.h"namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();void timeOUt();          //处理每一秒发射的信号槽函数void dealClose();        //防止不按stop而直接按右上角colse,而导致的线程没有关闭的槽函数signals:startThread();           //触发线程处理函数的信号private slots:void on_buttonstart_clicked();void on_buttonstop_clicked();private:Ui::Widget   *ui;MyThread_qt5 *myT;      //自定义线程对象QThread      *thread;   //线程对象
};#endif // WIDGET_H

4)主线程.cpp文件:

#include "widget.h"
#include "ui_widget.h"
#include<QDebug>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);myT= new MyThread_qt5;  //不能指定父对象,故他要手动delete.线程不能处理图形界面即对话框这种框,但可以利用他利用他带参数的信号传出来到主线程 connect的第五个参数thread= new QThread(this);myT->moveToThread(thread);qDebug()<<"主线程号: "<<QThread::currentThread();// 调用线程处理函数connect(this,&Widget::startThread,myT,&MyThread_qt5::dealMsg); //参数1不熟,可由参数2得出// 线程数据处理完毕connect(myT,&MyThread_qt5::isDone,this,&Widget::timeOUt);// 防止不按stop而直接按右上角colse,而导致的线程没有关闭connect(this,&Widget::destroyed,this,dealClose);}Widget::~Widget()
{delete ui;
}// 关键槽函数 启动新线程去处理多任务
void Widget::on_buttonstart_clicked()
{if(thread->isRunning() == true){return;                      //线程还在继续没必要start}myT->setFlag(false);thread->start();                 //只是启动线程,没有启动线程函数//直接调自定义线程函数,导致主线程与子线程id一样,即处于同一线程//myT->dealMsg();//只能通过信号和槽的方式调用   即再定义一个信号去触发自定义类的dealMsg(),然后通过发送该信号就可以调用了emit startThread();              // 必须通过信号和槽调用线程函数与间接调用run不一样}//处理每一秒发射的信号槽函数
void Widget::timeOUt()
{static int i=0;i++;ui->lcdNumber->display(i);
}void Widget::on_buttonstop_clicked()
{if(thread->isRunning() == false){return;                            //如果停止就没必要再继续. 按钮一般都有作这些判断.  嫌多可以不写}myT->setFlag(true);                    // 设置了标志位,但重新开始按下start时也要将其设回false,以至于可以继续循环thread->quit();thread->wait();                        // while的标志位设置先看下一条的注释,在进行解决// 仍然不能完整关闭线程 可以用标志位去解决 即将while(1)中的1改成相应标志位   即上面要先改变标志位
}void Widget::dealClose()
{on_buttonstop_clicked();               // 直接调用就行delete myT;                            // 因为他没有指定父对象
}

5)主函数:一样的。

6)ui界面:

更多推荐

53黑马QT笔记之Qt下创建新线程之Qt5版本

本文发布于:2024-02-19 16:08:41,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1765111.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:线程   黑马   版本   笔记   Qt

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!