0

何が起こっているかの簡単な概要: Qt の を使用して GET リクエストを実行しようとしていQNetworkAccessManagerますが、関数のコールバック関数QObject::connect(..)が呼び出されていません。私の質問はQObject::connect、あるオブジェクトから呼び出すことができますが、別のオブジェクトのスロットに接続できます (オブジェクトとスロットの両方へのポインターがある場合) - 詳細については以下を参照してください。

私の最終的な目標は、データを POST することです (ログイン関数であるため)。最終的に同じ問題に苦しんでいた POST リクエスト コードがありました - コールバック関数が呼び出されていません。なので、まずは簡単な GET リクエストができるようになりたいと思っています。

私は現在、 LoginWindow クラスLoginWindowのスロットを呼び出すボタンを備えた QMainWindowを持っています。doLogin()これはすべて、期待どおりに機能します。LoginWindow には というpublic slots関数もありますloginResponse(QNetworkReply* response)

//---LoginWindow.h

...

public slots:
    void doLogin();
    void loginResponse(QNetworkReply* response)

...

//---LoginWindow.cpp

LoginWindow::LoginWindow(QWidget *parent) :
    QMainWindow(parent),
ui(new Ui::LoginWindow)
{
    ui->setupUi(this);
    ui->username_le->setFocus();
}

void LoginWindow::doLogin()
{
   MyProduct::Network network(this);
    qDebug() << "Logging in...";

    //Here I call network.login from LoginWindow and pass 
    //references to the Slot I want to use and the LoginWindow itself
    network.login(
        ui->username_le->text(), //username
        ui->password_le->text(), //password
        this,                    //reference to this object (LoginWindow*)
        SLOT(loginResponse(QNetworkReply*)) //loginResponse slot
    );
}

void LoginWindow::loginResponse(QNetworkReply* response)
{
    qDebug() << "Log in complete";
}

次に、MyProduct名前空間の下に という別のクラスがありますNetwork。上記のように、Networkログインと呼ばれる機能があります。ここにあります:

void MyProduct::Network login(QString username, QString password, QObject *receiver, const char *slot)
{
    QNetworkRequest request(QUrl(API_ROOT + LOGIN_PATH)); //"http://localhost/basic/login.php"
    request.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");

    //nam = QNetworkAccessManager* declared in the constructor
    QObject::connect(nam,SIGNAL(finished(QNetworkReply*)), receiver, slot);

    qDebug() << "Posting login data...";
    nam->get(request);
}

ここでの目標はNetwork、任意の数のウィンドウで使用および接続できるログイン機能をクラスに作成することです (ユーザーは複数の場所からログインできるため)。しかし、私は応答を得ていません -LoginWindow::loginResponse実行されていません。

コンソールに「Logging in...」と「Posting login data」の出力が表示されますが、「Log in complete」は表示されません。

誰かが私を正しい方向に向けたり、私が頭がおかしい、またはこれは悪い考えだと言ってくれませんか?

前もって感謝します!

4

1 に答える 1

1

QNetworkAccessManager非同期で動作することに注意してください。ネットワーク操作が発生している間、get()メソッドはブロックされません。すぐに戻ります。(詳細については、ドキュメントの詳細な説明セクションを参照してください。)

これは、Qt のネットワーク関連 API の典型的な例です。データがネットワーク上を移動するのを待っている間にアプリケーションがフリーズするのは通常望ましくないからです。

namこれが意味することは、GET 要求が実際に終了するのに十分な時間、インスタンスが生きていないということです。クラスのインスタンスは、スタックに割り当てられているためProduct::Network、呼び出しの直後に削除されます。login()コードは見えませんが、QNetworkAccessManager同様にクリーンアップされていると思います。

オブジェクトの有効期間を延長するnetworkと、最終的にスロットが呼び出されることがあります。


また、これは好みの問題ですが、レシーバーとスロットを関数に渡さないようにする方がクリーンだと思いますlogin()NetworkAPI の一部としてクラスで独自のシグナルを宣言し、クラス内のシグナルに接続することをお勧めしますLoginWindow

于 2012-11-28T06:37:47.813 に答える