簡體   English   中英

為什么這個Qt信號從不發射?

[英]Why does this Qt signal never get emitted?

我正在嘗試從網頁中獲取數據,但是信號finished()從未發出!!! 我知道我一定在做錯事,但無法弄清楚那是什么。

# webservice.h
class WebService:public QObject
{
    Q_OBJECT

 public:
    explicit WebService(QObject *parent=0);
    void getRequest(const QString &urlString);

signals:
    void networkError(QNetworkReply::NetworkError ne);
    void finished(QNetworkReply*);

public slots:
    void parseNetworkResponse(QNetworkReply* finished);

private:
    QNetworkAccessManager *netMgr;

public:
    QByteArray data;
};

#webservice.cpp
WebService::WebService(QObject *parent):QObject(parent)
{
    netMgr = new QNetworkAccessManager;

    connect(netMgr, SIGNAL(finished(QNetworkReply*)),
                 this, SLOT(parseNetworkResponse(QNetworkReply*)));
}

void WebService::getRequest(const QString &urlString)
{
    QUrl url(urlString);
    QNetworkRequest req;
    emit finished(netMgr->get(req));
}

void WebService::parseNetworkResponse(QNetworkReply *finished)
{
    if (finished->error() != QNetworkReply::NoError)
    {
        emit networkError(finished->error());
        return;
    }

    data = finished->readAll();

   qDebug() << data;
}

data永遠不會得到預期的值。

您沒有將URL傳遞給您創建的QNetworkRequest 嘗試:

QNetworkRequest req(url);

WebService::getRequest()內部。


根據要求,對源進行了修改,使其可以在QtCreator中作為控制台應用程序項目中的單個main.cpp文件進行編譯和工作:

#include <QCoreApplication>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QUrl>
#include <QByteArray>
#include <QString>

#include <QDebug>

//# webservice.h
class WebService:public QObject
{
    Q_OBJECT

 public:
    explicit WebService(QObject *parent=0);
    void getRequest(const QString &urlString);

signals:
    void networkError(QNetworkReply::NetworkError ne);
    void finished(QNetworkReply*);

public slots:
    void parseNetworkResponse(QNetworkReply* finished);

private:
    QNetworkAccessManager *netMgr;

public:
    QByteArray data;
};

//#webservice.cpp
WebService::WebService(QObject *parent):QObject(parent)
{
    netMgr = new QNetworkAccessManager;

    connect(netMgr, SIGNAL(finished(QNetworkReply*)),
                 this, SLOT(parseNetworkResponse(QNetworkReply*)));
}

void WebService::getRequest(const QString &urlString)
{
    QUrl url(urlString);
    QNetworkRequest req(url);
    emit finished(netMgr->get(req));
}

void WebService::parseNetworkResponse(QNetworkReply *finished)
{
    if (finished->error() != QNetworkReply::NoError)
    {
        qDebug() << "QNetworkReply error: " << finished->error();
        emit networkError(finished->error());
        return;
    }

    data = finished->readAll();

   qDebug() << data;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    WebService web;
    web.getRequest("http://www.google.com");

    return a.exec();
}

#include "main.moc"

進行的較小修改:

  • 添加了必要的標題
  • 添加了一個帶有適當URL的main() ,它調用了WebService::getRequest()
  • main.cpp文件的末尾添加了#include "main.moc" ,因此qmake可以將它作為單個獨立的.cpp文件正確地“ moc-ify”
  • 解決了上述問題的答案
  • 在錯誤情況下添加了qDebug()輸出

最后要做的一件事是在項目的.pro文件中添加QT += network ,以便將Qt網絡模塊添加到鏈接步驟和標頭搜索路徑中。


2013年10月15日更新

從您的評論看來,您希望QNetworkAccessManager::get()調用是同步的。 我添加了示例程序的另一個版本,它將在WebService::getRequest()阻塞,直到收到請求的finished信號為止。 請注意,此示例在錯誤處理方面的執行不多,並且如果netwrok請求未能及時完成,可能會執行得很差。 除了示例代碼或學習代碼以外,必須適當地處理錯誤和超時。

此示例中的基本思想是,異步Qt網絡模型中發出的信號由框架的事件循環驅動。 因此,當發出請求時,將創建一個新的“嵌套”事件循環,然后WebService::getRequest()函數執行該循環(並保持在那里),直到finished信號的處理程序告訴事件循環退出為止。

#include <QCoreApplication>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QUrl>

#include <QEventLoop>

#include <QByteArray>
#include <QString>

#include <QDebug>

//# webservice.h


class WebService:public QObject
{
    Q_OBJECT

 public:
    explicit WebService(QObject *parent=0);
    void getRequest(const QString &urlString);

signals:
    void networkError(QNetworkReply::NetworkError ne);
    //void finished(QNetworkReply*);

public slots:
    void parseNetworkResponse(QNetworkReply* finished);

private:
    QNetworkAccessManager *netMgr;
    QEventLoop request_event_loop;

public:
    QByteArray data;
};

//#webservice.cpp
WebService::WebService(QObject *parent):QObject(parent)
{
    netMgr = new QNetworkAccessManager;

    connect(netMgr, SIGNAL(finished(QNetworkReply*)),
                 this, SLOT(parseNetworkResponse(QNetworkReply*)));
}

void WebService::getRequest(const QString &urlString)
{
    QUrl url(urlString);
    QNetworkRequest req(url);
    netMgr->get(req);

    request_event_loop.exec();        // wait here until the WebService::parseNetworkResponse() slot runs
    // emit finished(netMgr->get(req));
}

void WebService::parseNetworkResponse(QNetworkReply *finished)
{
    qDebug() << "enter parseNetworkResponse()";

    if (finished->error() != QNetworkReply::NoError)
    {
        qDebug() << "QNetworkReply error: " << finished->error();
        emit networkError(finished->error());
    }
    else {
        data = finished->readAll();

        qDebug() << data;
    }

    qDebug() << "request_event_loop.exit()";
    request_event_loop.exit();
    qDebug() << "exit parseNetworkResponse()";
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    WebService web;

    qDebug() << "main() getRequest()";
    web.getRequest("http://www.stackoverflow.com");
    qDebug() << "main() getRequest() completed";

    return a.exec();
}

#include "main.moc"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM