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();
}

 

posted @ 2021-12-02 11:40  osbreak  阅读(290)  评论(0编辑  收藏  举报