2

Qt 4.8.1を実行しています

QNetworkRequest を使用してリクエストを送信しようとすると、「QEventLoop: Cannot be used without QApplication」エラーが発生します。イベントループ内で実行していると思います。

void WebLoader::load()
{
    QNetworkRequest request;
    request.setUrl(QUrl("http://www.bbc.co.uk/"));

    QNetworkAccessManager *manager = new QNetworkAccessManager();
    connect(manager, SIGNAL(finished(QNetworkReply*)),
             this, SLOT(checkForUpdateFinished(QNetworkReply*)));

    QNetworkReply *reply = manager->get(request);
    connect(reply, SIGNAL(readyRead()), this, SLOT(checkForUpdateSlot()));
}

manager->get(reply) 呼び出しは戻りません。

この関数は、メニュー項目がクリックされたときに呼び出されます。そのスタック トレースに QWidget::event(QEvent) があります。アプリケーションは確実に実行されており、複雑な UI の残りの部分が機能しています。

私が試したバリエーションとして:

  1. 新しい QNetworkAccessManager(mainWindow) を使用 - mainWindow は QMainWindow から継承します
  2. 新しい QNetworkAccessManager(application) を使用 - アプリケーションは QApplication から継承します
  3. customEvent から load() を呼び出す
  4. タイマー コールバックから load() を呼び出す

[編集]

現在、MainWindow コンストラクターで QNetworkAccessManager を構築しています。

MainWindow::MainWindow() : queryAnalyser(NULL)
{
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(managerFinished(QNetworkReply*)));

managerFinished が呼び出されていません。

デバッグ IO を取得しています: 'QObject: 別のスレッドにある親の子を作成できません。(親は MainWindow(0x28fcd0)、親のスレッドは QThread(0x4862828)、現在のスレッドは QThread(0x7d90b70) '

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    WXApplication *a = WXApplication::getApp();

    MainWindow mainWin;

    mainWin.show();
    mainWin.checkArgs();
    return app.exec();
}
4

1 に答える 1

0

QNetworkAccessManagerリクエストを検知するメソッドの最後で、が破棄されていないことを確認してください。破壊された場合、破壊されたものは接続されたスロットQNetworkAccessManagerに信号を送信できないため、リクエストは失われます。finished()

これはまさにWebLoader::load();メソッドで起こったことです。変数はメソッドのmanager実行中にのみ存在し、応答を受け取る前にメソッドが終了します。

あなたができることは、グローバル変数に入れて、QNetworkAccessManagerあなたがそれを必要とするたびにこのグローバル変数を使うことです:

Afile.hpp:

//...

#include <QNetworkAccessManager>
extern QNetworkAccessManager QNAM;

//...

Afile.cpp:

//...

#include "afile.hpp"
QNetworkAccessManager QNAM = QNetworkAccessManager();

//...

あなたのコードで(WebLoader::load();例えば):

//...
#include "afile.hpp"
//...
QNetworkAccessManager * manager = &QNAM;
//...

リクエストでは、元のオブジェクトを「タグ付け」リクエストに設定し、適切なメソッドが適切な応答を処理するようにします。

void WebLoader::load()
{
    QNetworkRequest request;
    request.setUrl(QUrl("http://www.bbc.co.uk/"));
    request.setOriginatingObject(this);

    QNetworkAccessManager * manager = &QNAM;
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(checkForUpdateFinished(QNetworkReply*)));

    manager->get(request);
}

void WebLoader::checkForUpdateFinished(QNetworkReply* reply)
{
    if (reply == 0 || reply->request().originatingObject() != this)
    {
        return;
    }

    disconnect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(checkForUpdateFinished(QNetworkReply*)));

    // Reply treatment

    reply->deleteLater();

    // ...
}

コンストラクターで、必要がない場合はMainWindow忘れるthisか、QNAMグローバル変数を使用します。

于 2012-11-17T03:36:15.423 に答える