Qt请求永远不会触发finished()信号

时间:2012-10-20 16:58:00

标签: c++ qt qthread

我有一些非常奇怪的东西我有这个代码:

我想我知道出了什么问题,但我不知道如何解决它。 这就是我所拥有的: 当我把断点放在int test = 0时; 它在到达HttpClient中的httpFinished()插槽之前到达那里,mybe这是问题吗? 在main.cpp中

---------------------------------------------------------------------------------------------------------
@while (i.hasNext())
{
i.next();

ThreadWorker* pThreadWorker = new ThreadWorker();
pThreadWorker->setUrl(sUrl);
QThreadPool::globalInstance()->start(pThreadWorker);
}
QThreadPool::globalInstance()->waitForDone();



---------------------------------------------------------------------------------------------------------
void ThreadWorker::run()
{
  startWork();
}

void ThreadWorker::startWork()
{
 m_pHttpClient = new HttpClient();
 m_pHttpClient->startRequest(m_url);
 int test = 0;


}

--------------------------------- HttpClient  based on the http example from Qt -----------------------------------

HttpClient::HttpClient()
{
  m_networkManager = new QNetworkAccessManager(this);
  connect(m_networkManager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
            this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*)));

 #ifndef QT_NO_OPENSSL
    connect(m_networkManager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
            this, SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
 #endif
}



void HttpClient::startRequest(QUrl url)
{
   m_url.setUrl("http://qt.nokia.com/");
  QNetworkRequest request; 
  request.setUrl(m_url);

 reply = m_networkManager->get(request);


 connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
         this, SLOT(slotError(QNetworkReply::NetworkError)));

 connect(reply,SIGNAL(finished()),
            this, SLOT(httpFinished()));

    connect(reply, SIGNAL(readyRead()),
            this, SLOT(httpReadyRead()));

    connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
            this, SLOT(updateDataReadProgress(qint64,qint64)));


}

私有插槽下的httpFinished()函数:从未触发,为什么?

更新问题

1 个答案:

答案 0 :(得分:1)

由于在线程中创建了HttpClientQNetworkAccessManager个对象,它们自动属于该线程(参见QObject::moveToThread),并且它们都需要在该线程中运行的事件循环,让QNAM完成任何工作,并使QObject派生类能够执行插槽。

您可以在QThread::exec()中添加对run()的调用来运行该事件循环(如果您使用的是QThread):

void Thread::run()
{
    startWork();
    exec();
}

或创建并启动QEventLoopquit()广告位必须连接到某处才能停止循环(例如finished()类中的HttpClient信号。工作完成后发出):

void ThreadWorker::run()
{
    startWork();
    QEventLoop loop;
    QObject::connect(m_pHttpClient, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec(); 
}

此外,since Qt 4.8QNetworkAccessManager是多线程的,因此您可能不需要自己使用线程。