QT多线程,QT4.7之前是承继 QThread 的方式,比较简单,而 QT5之后,使用了信号和槽的方式,比较灵活。(版本信息可能有误)
下面是对QT线程信息的注意事项
//线程处理函数内部不允许操作图形界面
//connect 的第五个参数作用,连接方式:默认、队列、直接
//多线程时才有意义
//默认的时候
//如果是多线程,默认用队列
//如果是单线程,默认使用直接方式
/*队列方式:槽函数所在的线程和接收者在同一个线程中
如:connect(this,&Widget::startThread,myT,&MyThread::myTimeout);
中的 myT,&MyThread::myTimeout (槽函数所在的线程和接收者在同一个线程中)
*/
/*
* 直接:槽函数所在线程和发送者一样
*/
下面是一个多线程的例子:
运行如下图所示:
主函数:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
myT = new MyThread; //不能指定父对像
//创建子线程
thread = new QThread(this);
//把自定义的线程加入到子线程中
myT->moveToThread(thread);
//处理MyThread::mySignal 发来的信息(每隔1s发来的信息)
connect(myT,&MyThread::mySignal,this,&Widget::dealSignal);
qDebug()<<"主线程号:"<<QThread::currentThreadId();
//调用线程 信号是主框口发的。只要信号来了,就调用这个线程的处理函数
connect(this,&Widget::startThread,myT,&MyThread::myTimeout);
connect(this,&Widget::destroyed,this,&Widget::dealMs);
//线程处理函数内部不允许操作图形界面
//connect 的第五个参数作用,连接方式:默认、队列、直接
//多线程时才有意义
//默认的时候
//如果是多线程,默认用队列
//如果是单线程,默认使用直接方式
/*队列方式:槽函数所在的线程和接收者在同一个线程中
如:connect(this,&Widget::startThread,myT,&MyThread::myTimeout);
中的 myT,&MyThread::myTimeout (槽函数所在的线程和接收者在同一个线程中)
*/
/*
* 直接:槽函数所在线程和发送者一样
*/
}
Widget::~Widget()
{
delete ui;
delete myT; //释放资源
}
void Widget::on_pushButton_clicked()
{
if(thread->isRunning() == true)
{
return;
}
//如果启动线程,但是没有启动线程处理函数
thread->start();
//不能直接调用线程处理函数
//直接调用,导致线程函数和主线程是在同一个线程中。
//myT->myTimeout();
myT->setFlag(false);
//只能通过 SIGNAL - SLOT 方法调用
emit startThread();
}
void Widget::dealSignal()
{
static int i=0;
i +=1;
ui->lcdNumber->display(i);
}
void Widget::dealMs()
{
myT->setFlag();
thread->quit();
thread->wait();
}
void Widget::on_pushButton_2_clicked()
{
if(thread->isRunning() == false)
{
return;
}
//这样虽然能停止窗口,但是线程依然在运行。
/*
thread->quit();
thread->wait();
*/
//这儿使用标识位
myT->setFlag();
thread->quit();
thread->wait();
}
MyThread.cpp
#include "mythread.h"
MyThread::MyThread(QObject *parent) : QObject(parent)
{
isStop = false;
}
void MyThread::myTimeout()
{
while(!isStop)
{
//每一秒钟发个信息
//发给谁?
QThread::sleep(1);
emit mySignal();
qDebug()<<"子线程号:"<<QThread::currentThreadId();
}
}
void MyThread::setFlag(bool flag)
{
isStop = flag;
}