2016-03-25 189 views
0

我想在Qt中實現某種回調。在Qt中實現回調

我有一個類叫做ApiHandler作出請求。我應該有一種方法將回調函數傳遞給makeRequest,並在回覆已完成時執行它。 我知道使用std :: function/std :: bind。但也許有辦法使用Qt來做到這一點?老虎機?或者在這種情況下使用std :: function/std :: bind的更詳細的解釋。

謝謝!

typedef void (*callback)(); 
void ApiHandler::makeRequest(QString method, QMap<QString, QString> parameters, callback) 
{ 
    QUrl url = this->buildCall(method, parameters); 

    connect(this->manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*, callback))); 

    QNetworkRequest request; 
    request.setUrl(url); 
    request.setRawHeader("User-Agent", "Test"); 

    QNetworkReply *reply = this->manager->get(request); 
    connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead())); 
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError(QNetworkReply::NetworkError))); 
    connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(slotSslErrors(QList<QSslError>))); 
} 
void ApiHandler::replyFinished(QNetworkReply* reply, callback) 
{ 
    qDebug() << "replyFinished" << reply->url(); 
    QJsonDocument j = QJsonDocument::fromJson(reply->readAll()); 
    if (j.isEmpty()) { 
     // throw error 
    } 

    // call the callback with "j" as parameter 
    // callback(j) 

    reply->deleteLater(); 
} 
+0

這是什麼情況下使用?只有在編譯時無法解析回調的情況下,您才需要std :: function。如果你知道所有的回叫,然後讓他們插槽。 – xvan

+0

我可以做出不同的調用,像這樣'QMap m; m [「user_id」] = this-> settings.value(USER_ID).toString(); ApiHandler * a = new ApiHandler; a-> makeRequest(「users.isAppUser」,m,testCallback);' 而我應該需要傳遞不同的回調。在示例中,如果我從應用程序開始調用此開始,我傳遞迴調來顯示警告,如果我從窗口調用此窗口,我傳遞迴調以顯示任何用戶正在使用的應用程序。 – Alex

+0

您可以使用不同的對象,用於不同的信號,或[斷開並連接插槽](http://stackoverflow.com/questions/28524925/how-to-disconnect-a-signal-with-a-slot-temporarily-in -qt)on context – xvan

回答

3

既然你已經在使用信號和槽和makeRequest參數已經基於Qt的類型,你可以只通過在從Qobject派生並具有信號的Request實例。然後

class Request : public QObject 
{ 
public: 
     QString method(); 
     QMap<QString, QString> parameters(); 

signals: 
    void received(QJsonDocument); 
}; 

replyFinished可以通過回調

void ApiHandler::replyFinished(QNetworkReply* reply, Request* request) 

當eveything準備好你剛剛火信號的Request代替。

request->received(j); 

在通過Request之前,您只需連接任何你想要的。

connect(request, &Request::received, [=](QJSonDocument) { 
    // whatever ... 
});