QT多线程方式二:
1)设定一个类,继承于QObject
2)类中设置一个线程函数(只有一个是线程函数),内部使用一个while循环
3)创建线程对象,不能指定父对象
4)创建QThread子线程对象
5)自定义线程类加入子线程
a) thread—>start() 只是开启了线程,并没有启动线程处理函数
b)线程函数的启动,必须要通过signal——slot
//线程函数类 mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
class mythread : public QObject
{
Q_OBJECT
public:
explicit mythread(QObject *parent = nullptr);
void myTimeOut(); //信号处理函数
void setStop(bool isStop = true);
signals:
void mysignal();
public slots:
private:
bool isStop;
};
#endif // MYTHREAD_H
//线程函数类 mythread.cpp
#include "mythread.h"
#include <QThread>
#include <QDebug>
mythread::mythread(QObject *parent) : QObject(parent)
{
isStop = false ;
}
void mythread::myTimeOut()
{
while ( !isStop ) {
QThread::sleep(1);
emit mysignal();
qDebug()<<"子线程号: "<<QThread::currentThreadId();
if(isStop)
break;
}
}
void mythread::setStop(bool flag)
{
isStop = flag ;
} 主体类 threadtest.h
#ifndef THREADTEST_H
#define THREADTEST_H
#include <QWidget>
#include "mythread.h"
namespace Ui {
class threadtest;
}
class threadtest : public QWidget
{
Q_OBJECT
public:
explicit threadtest(QWidget *parent = nullptr);
~threadtest();
void dealSignal();
void threadStop();
signals:
void startThread(); //启动子线程的信号
private slots:
void on_ButtonStart_clicked();
void on_ButtonStop_clicked();
private:
Ui::threadtest *ui;
mythread *myT;
QThread *thread;
};
#endif // THREADTEST_H
主体类 threadtest.cpp
#include "threadtest.h"
#include "ui_threadtest.h"
#include <QThread>
#include <QDebug>
threadtest::threadtest(QWidget *parent) :
QWidget(parent),
ui(new Ui::threadtest)
{
ui->setupUi(this);
//动态分配空间,不能指定父对象
myT = new mythread();
//创建子线程
thread = new QThread(this);
//自定义的线程加入子线程
myT->moveToThread(thread);
connect(myT,&mythread::mysignal,this,&threadtest::dealSignal);
qDebug()<<"主线程号: "<<QThread::currentThreadId();
connect(this,&threadtest::startThread,myT,&mythread::myTimeOut);
connect(this,&threadtest::destroyed,this,&threadtest::threadStop);
//线程函数处理内部,不允许处理图形界面
//线程后台处理数据
//connect 第五个参数 的作用 ,只有在多线程才有意义 :1. 默认 2. 队列 3 直接
//默认的时候
//如果是多线程,默认使用队列
//如果是单线程,默认是使用直接
//队列方式:槽函数所在线程和接受者一样
//直接方式:槽函数所在线程和发送者一样
}
threadtest::~threadtest()
{
delete ui;
}
void threadtest::on_ButtonStart_clicked()
{
if(thread->isRunning() == true)
{
return;
}
thread->start(); //启动线程,但是没有启动线程函数
myT->setStop(false);
//不能直接调用线程处理函数,如果直接调用,那么线程处理函数和主线程在同一个线程
//myT->TimeOut(); //主线程号: 0xa2f8 子线程号: 0xa2f8 19:39:47: 程序异常结束。
//线程函数的启动只能通过signal-slot
emit startThread();
}
void threadtest::dealSignal()
{
static int i = 0 ;
i++;
ui->lcdNumber->display(i);
}
void threadtest::on_ButtonStop_clicked()
{
if(thread->isRunning() == false)
{
return;
}
myT->setStop(true);
thread->quit();
thread->wait();
}
void threadtest::threadStop()
{
on_ButtonStop_clicked();
delete myT;
}
原文地址:https://www.cnblogs.com/AmyBKLP/p/11700844.html
时间: 2024-11-13 06:49:39