赞
踩
QThread
类来实现QThread
代表⼀个在应⽤程序中可以独⽴控制的线程,也可以和进程中的其他线程共享数据QThread
对象管理程序中的⼀个控制线程,QThread
在run()
中开始执⾏
run()
通过调⽤exec()
来启动事件循环,并在线程内运⾏Qt事件循环QThread
类,重写run()
函数 --> 多态QThread
,并且只有⼀个线程处理函数重写⽗类中的run()
run()
,需要使⽤对象来调⽤start()
实现线程启动
start()
底层就是调用OS API创建线程,新县城创建后自动执行run()
// thread.h class Thread : public QThread { Q_OBJECT public: Thread(); // 重要的目的是重写父类的 run 方法. void run(); signals: void Notify(); }; // thread.cpp void Thread::run() { // 每过一秒, 通过信号槽, 来通知主线程, 负责更新的界面内容 for (int i = 0; i < 10; i++) { // sleep 本身是 QThread 的成员函数, 就可以直接调用 sleep(1); // 发送一个信号, 通知主线程 emit Notify(); } } ------------------------------------------------------------------------- // widget.h class Widget : public QWidget { // ... Thread thread; void Handle(); }; // widget.cpp // 构造函数中 { // 连接信号槽, 通过槽函数更新界面 connect(&thread, &Thread::Notify, this, &Widget::Handle); // 要启动一下线程. thread.start(); } void Widget::handle() { // 此处修改界面内容. int value = ui->lcdNumber->intValue(); value--; ui->lcdNumber->display(value); }
QObject
类,通过moveToThread(thread)
,交给thread执⾏moveToThread(QThread* targetThread)
QObject
类QThread
类的对象,可以指定其⽗对象QThread
类的对象中使⽤start()
启动线程
start()
只是启动了线程,但是并没有开启线程处理函数// thread.h class MyThread : public QObject { Q_OBJECT public: // ... void Thread(); void SetFlag(bool flag = true); signals: void Notify(); private: bool isStop() = false; }; // thread.cpp void MyThread::Thread() { while(!isStop) { QThread::sleep(1); emit Notofy(); qDebug() << " ⼦线程号: " << QThread::currentThread(); if(isStop) { break; } } } void MyThread::SetFlag(bool flag) { isStop = flag; } ------------------------------------------------------------------------- // widget.h class Widget : public QWidget { // ... MyThread* myThread; QThread* thread; signals: void StartSignal(); // 启动子线程信号 private slot: void on_startPushbutton_clicked(); void on_closePushbutton_clicked(); void DelSignals(); void DealClose(); }; // widget.cpp // 构造函数中 { // 动态分配空间,不能指定⽗对象 myThread = new MyThread(); // 创建子线程 thread = new QThread(this); // 将⾃定义的线程加⼊到⼦线程中 myThread->moveToThread(thread); connect(myThread, &MyThread::Notify, this, &Widget::DelSignals); connect(this, &Widget::StartSignal, myThread, &MyThread::Thread); connect(this, &Widget::destroyed, this, &Widget::DealClose); } void MyWidget::on_startPushbutton_clicked() { if(thread->isRunning() == true) { return; } // 启动线程但是没有启动线程处理函数 thread->start(); // 不能直接调⽤线程处理函数,直接调⽤会导致线程处理函数和主线程处于同⼀线程 emit StartSignal(); } void MyWidget::DelSignals() { static int i = 0; i++; ui->lcdNumber->display(i); } void MyWidget::on_closePushbutton_clicked() { if(thread->isRunning() == false) { return; } myThread->SetFlag(); thread->quit(); thread->wait(); } void MyWidget::DealClose() { delete myThread; on_closePushbutton_clicked(); }
connect()
第五个参数表⽰的是连接的⽅式,且只有在多线程的时候才意义connect()
第五个参数Qt::ConnectionType
,⽤于指定信号和槽的连接类型,同时影响信号的传递⽅式和槽函数的执⾏顺序
Qt::AutoConnection
:会根据信号和槽函数所在的线程⾃动选择连接类型
Qt:DirectConnection
类型Qt::QueuedConnection
类型Qt::DirectConnection
:当信号发出时,槽函数会⽴即在同⼀线程中执⾏
Qt::QueuedConnection
:当信号发出时,槽函数会被插⼊到接收对象所属的线程的事件队列中,等待下⼀次事件循环时执⾏
Qt::BlockingQueuedConnection
:与Qt:QueuedConnection
类似
Qt::UniqueConnection
:这是⼀个标志,可以使⽤|
与上述任何⼀种连接类型组合使⽤void terminate()
:直接关闭线程不等待线程任务结束void quit()
:等待线程任务结束之后关闭线程Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。