2012-11-28 38 views
0

發生了什麼事情的快速概覽:我想使用Qt的QNetworkAccessManager做一個GET請求,但我的QObject::connect(..)函數上的回調函數沒有被調用。我的問題是我可以從一個對象調用QObject::connect,但連接到另一個對象的一個​​插槽(因爲我有一個指向對象和插槽的指針) - 請參閱下面的更多細節。C++ - Qt QObject ::連接GET請求使用各類

我最終的目標是發佈數據(因爲它是一個登錄函數),我有POST請求代碼,最終遭受同樣的問題 - 回調函數沒有被調用。所以我希望能夠首先做一個簡單的GET請求,一旦我有了,我想我會從那裏自行處理。

我目前有一個QMainWindow LoginWindow,帶有一個按鈕,它在LoginWindow類中調用了一個槽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有一個叫做login的函數。那就是:

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未運行。

我在控制檯中看到「正在登錄...」和「正在登錄數據」輸出,但沒有顯示「登錄完成」。

任何人都可以請指點我在正確的方向或告訴我我瘋了,或者這是一個壞主意?

在此先感謝!

回答

1

請注意,QNetworkAccessManager異步運行。在網絡操作發生時,get()方法不會阻塞;它立即返回。 (請參閱文檔Detailed Description以瞭解更多信息。)

這是Qt網絡相關API的典型代碼,因爲您通常不希望應用程序在等待數據在網絡中移動時凍結。

這意味着您的實例nam的活動時間不夠長,無法讓GET請求實際完成。 Product::Network類的實例在調用login()後立即被刪除,因爲它在堆棧中分配。雖然我看不到代碼,但我猜它也會清理QNetworkAccessManager

如果延長對象的使用期限,您可能會發現您的插槽最終會被調用。


此外,這是更偏好的問題,但我認爲這將是更清潔,以避免將接收器和插槽您login()功能。我建議在Network類中聲明自己的信號作爲其API的一部分,並連接到類LoginWindow中的類。

+0

就是這樣! 'nam'只在本地範圍內,並且在請求返回之前被銷燬。非常感謝你。我現在正在考慮爲我的網絡課程製作自己的信號。 – Jace