Qt::线程::继承QThread
一个QThread对象管理一个线程。QThread的执行从run()函数的执行开始,在Qt自带的QThread类中,run()函数通过调用exec()函数来启动事件循环机制,并且在线程内部处理Qt的事件。
QThread只有run函数是在新线程里的,其他所有函数都在QThread生成的线程里
子线程中能不能进行UI操作:
Qt中的UI操作,比如QMainWindow、QWidget之类的创建、操作,只能位于主线程!
主线程负责提供界面,子线程负责无UI的单一任务,通过“信号-槽”与主线程交互。
#include <QObject> #include <QThread> class ThreadFromQThread : public QThread { Q_OBJECT signals: void message(const QString& info); void progress(int present); public: ThreadFromQThread(QObject* par); ~ThreadFromQThread(); void setSomething(); void getSomething(); void setRunCount(int count); void run(); void doSomething(); private: int m_runCount; };
#include "threadhandle.h" #include <QDebug> ThreadFromQThread::ThreadFromQThread(QObject* par) : QThread(par) ,m_runCount(20) { } ThreadFromQThread::~ThreadFromQThread() { m_thread->wait(); qDebug() << "ThreadFromQThread::~ThreadFromQThread()"; } void ThreadFromQThread::setSomething() { msleep(500); QString str = QString("%1->%2,thread id:%3").arg(__FUNCTION__).arg(__FILE__).arg((int)QThread::currentThreadId()); emit message(str); } void ThreadFromQThread::getSomething() { msleep(500); emit message(QString("%1->%2,thread id:%3").arg(__FUNCTION__).arg(__FILE__).arg((int)QThread::currentThreadId())); } void ThreadFromQThread::setRunCount(int count) { m_runCount = count; emit message(QString("%1->%2,thread id:%3").arg(__FUNCTION__).arg(__FILE__).arg((int)QThread::currentThreadId())); } void ThreadFromQThread::run() { int count = 0; QString str = QString("%1->%2,thread id:%3").arg(__FILE__).arg(__FUNCTION__).arg((int)QThread::currentThreadId()); emit message(str); while(1) { sleep(1); ++count; emit progress(((float)count / m_runCount) * 100); emit message(QString("ThreadFromQThread::run times:%1").arg(count)); doSomething(); if(m_runCount == count) { break; } } } void ThreadFromQThread::doSomething() { msleep(500); emit message(QString("%1->%2,thread id:%3").arg(__FUNCTION__).arg(__FILE__).arg((int)QThread::currentThreadId())) m_thread = new ThreadFromQThread(this) m_thread->setRunCount(10); connect(m_thread, &ThreadFromQThread::message, this, &Widget::receiveMessage); connect(m_thread, &ThreadFromQThread::progress, this, &Widget::progress); //connect(m_thread, &QThread::finished, this, &Widget::onQThreadFinished); //善用QObject::deleteLater 和 QObject::destroyed来进行内存管理 //如果是堆分配的话,可以通过deleteLater来让线程自杀 //new出来,这样在析构时就需要调用QThread::wait() //connect(m_thread, &QThread::finished, m_thread, &QObject::deleteLater); m_thread->start(); }
//在QThread执行start函数之后,run函数还未运行完毕,再次start,不会发生任何结果,QThread还是继续执行它的run函数,run函数不会被重新调用。
//虽然在线程未结束时调用start不会出现什么结果,但为了谨慎起见,还是建议在start之前进行判断
void Widget::on_pushButton_clicked() { if(m_thread->isRunning()) { return; } m_thread->start(); }