16、多线程
1、qt4.7以前版本处理方式,多线程的使用
1、多线程使用模板:
1、自定义一个类,继承于QThread,
class MyThread : public QThread { public: void run(); // 多任务执行函数 signals: void isDone(); // 处理完成后需要发送信号需要知道,线程处理完成任务 } void run() // 函数实现 { // 处理复杂任务 // 发送信号 任务处理完成 emit isDone(); }
2、使用的地方需要创建一个类对象
MyThread thread; // 在需要多任务的地方启动线程 // 不可以直接掉用run() // start() 间接调用run() thread.start(); // 启动线程
3、线程使用
2、多线程简单使用例子
Step 1、创建一个类继承QThread
#include <QThread> class myThread : public QThread { protected: void run(); // 重写虚函数 线程的入口函数 signals: void isDone(); // 发信号 说明线程结束了 };
Step 2、实现run()函数
void myThread::run() { qDebug() << ";正在睡觉"; sleep(5); // 任务处理代码 emit isDone(); // 发送信号 说明该线程结束了 }
Step 3、线程启动,转去执行run()
void Widget::on_buttonStart_clicked() { if(myTimer->isActive() == false) { myTimer->start(100); } // 需要多线程的地方 启动线程 thread->start(); // 启动线程 }
Step 4、等待run()发出线程结束信号,并处理信号
thread = new myThread(this); // 处理线程结束信号标志 connect(thread,&myThread::isDone,this,&Widget::dealPmythread);
Step 5、线程结束处理
void Widget::dealPmythread() { qDebug() << "deal over"; myTimer->stop(); // 线程结束了 进一步处理 }
Step 6、释放线程资源
// 窗口右上角X 关闭时,发出信号处理, 释放线程资源 connect(this,&Widget::destroyed,this,&Widget::closeThread);
Step 7、释放线程 函数实现
void Widget::closeThread() { thread->quit(); // 关闭线程 thread->wait(); // 等待线程处理完资源 }
4、比较方便的使用多线程 线程使用框图
1、设定一个类,继承于QObject
2、类中设置一个线程函数(只有一个是线程函数)

使用的全部代码
#include <QObject> #include <QThread> class myTHread : public QObject { Q_OBJECT public: void mytimeout(); // 处理多任务的函数 bool isStop = false; signals: void mysignal(); // 多任务处理完成发送的信号 }; #endif // MYTHREAD_H
// 任务处理函数实现
// 需要多任务处理的函数 void myTHread::mytimeout() { while(isStop == false) // 结束时可以停止线程 { if(isStop == true) { break; } QThread::sleep(1); qDebug() << "子线程号:" << QThread::currentThread(); emit mysignal(); // 发送信号 } }
主窗口类中
class myWidget : public QWidget { myTHread *myT; // 自定义线程对象 QThread *thread; // 线程对象 signals: void startThread(); // 启动线程信号 private slots: // 启动线程 void on_buttonStart_clicked(); void dealsignal(); // 处理线程发送过来的信号 // 停止线程 void on_buttonStop_clicked(); }
主窗口构造函数
// 分配空间 不能指定父对象 没有指定父对象最好最后 delete掉 myT = new myTHread(); // 创建子线程线程 thread = new QThread(this); // 把自定义线程加入到子线程中 myT->moveToThread(thread); qDebug() << "主线程号:"<<QThread::currentThread(); // 线程任务结束信号 connect(myT,&myTHread::mysignal,this,&myWidget::dealsignal); connect(this,&myWidget::startThread,myT,&myTHread::mytimeout); // thread->isRunning(); /* 线程处理函数内部不允许操作图形界面 弹出对话框也不行 * connect()第五个参数的作用: * 连接方式:默认、队列、直接 * 多线程的时候才会有意义: * 如果是多线程默认使用队列; * 如果是单线程,默认使用直接方式 * 队列:槽函数所在的线程和信号接收者一样 * 直接:槽函数所在线程和发送者一样; */
// 槽函数 void myWidget::dealsignal() { static int i=0; i++; ui->lcdNumber->display(i); } // 按钮槽函数 void myWidget::on_buttonStart_clicked() { myT->isStop = false; // 启动线程并没有启动线程处理函数 thread->start(); // 不能直接掉用线程处理函数 // 否则 会导致子线程与主线程程在同一个线程 // 只能通过信号---槽的形式调用startTread() emit startThread(); } // 按钮槽函数 void myWidget::on_buttonStop_clicked() { myT->isStop = true; // 停止线程 thread->quit(); // 线程退出 thread->wait(); // 等待线程资源释放 }
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号