/*******************************************************************************************/
一、为什么需要使用线程
图形界面中一旦使用了线程休眠,图形界面就不会刷新(不会动),呈现卡住无响应的状态。
这是由于图形界面中是单线程的
所以 很复杂的数据处理 耗时长的,就需要创建线程。
QThread 线程类,
qt中的线程睡眠函数:QThread::sleep();
void MyWidget::on_pushButton_clicked()
{
//如果定时器没有工作
if(myTimer->isActive() == false)
{
myTimer->start(100);
}
//很复杂的数据处理
//需要耗时5s
sleep(5);//图形界面中一旦使用了线程休眠,图形界面就不会刷新(不会动),呈现卡住无响应的状态。
//也就是说由于睡眠,导致前面启动了的定时器都不工作
myTimer->stop();//过了5s后图形界面才会有响应。但是
//此时是停了定时器,前面是睡眠 定时器也不工作,所以呈现出一直定时器一直不工作的状态
}
/*******************************************************************************************/
二、线程
1.Qt4.7以前 线程的使用方法:
1).自定义一个类,继承于QThread
class MyThread : public QThread
{
public:
void run();//只有这个是线程处理函数(和主线程不在同一个线程),虚函数。
}
2).使用自定义的类创建对象,并开启线程
MyThread myThread;
//启动线程
//注意不能直接调用run函数,否则还是在主线程里面运行,而不是在新线程里面
myThread.start();//间接调用run
3).返回处理结果,告诉处理完
可以在类中定义一个信号,然后在需要(处理好后)的时候发送这个信号,来告诉其他线程。
具体见图《线程1》
2.实现:
在项目中添加一个继承QThread的类,添加的时候注意由于这个不是控件,所以下拉框选择QObject,然后
再在文件中把基类改为QThread
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
protected:
//QThread的虚函数
//线程处理函数
//不能直接调用,通过start()间接调用
void run();
signals:
void isDone();
public slots:
};
void MyThread::run()
{
//很复杂的数据处理
//需要耗时5s
sleep(5);
emit isDone();
}
//分配空间
thread = new MyThread(this);
//处理线程中的信号,最好用这种传统的方式
connect(thread, &MyThread::isDone, this, &MyWidget::dealDone);
//当按窗口右上角x时,窗口触发destroyed(),否则关了窗口线程还会运行
connect(this, &MyWidget::destroyed, this, &MyWidget::stopThread);
void MyWidget::dealDone()
{
qDebug() << "it is over";
myTimer->stop(); //关闭定时器
}
void MyWidget::on_pushButton_clicked()
{
//如果定时器没有工作
if(myTimer->isActive() == false)
{
myTimer->start(100);
}
//启动线程,处理数据
thread->start();
}
void MyWidget::stopThread()
{
//停止线程,不是立马关闭,释放线程占用的内存,线程号等资源。和下面配合使用
thread->quit();//类似linux中,pthread_exit()
//等待线程处理完手头动作
thread->wait();//类似linux中,pthread_join , pthread_detach,
//terminate 强制结束,很暴力,往往会导致内存问题。所以一般不用
}
上述代码具体见《QThread》
1 #ifndef MYWIDGET_H 2 #define MYWIDGET_H 3 4 #include <QWidget> 5 #include <QTimer> //定时器头文件 6 #include "mythread.h" //线程头文件 7 8 namespace Ui { 9 class MyWidget; 10 } 11 12 class MyWidget : public QWidget 13 { 14 Q_OBJECT 15 16 public: 17 explicit MyWidget(QWidget *parent = 0); 18 ~MyWidget(); 19 20 void dealTimeout(); //定时器槽函数 21 void dealDone(); //线程结束槽函数 22 void stopThread(); //停止线程槽函数 23 24 private slots: 25 void on_pushButton_clicked(); 26 27 private: 28 Ui::MyWidget *ui; 29 30 QTimer *myTimer; //声明变量 31 MyThread *thread; //线程对象 32 }; 33 34 #endif // MYWIDGET_H